黑客教你定位手机芯片  BZOJ4912

访客4年前黑客文章775

建立新图,原图中每条边在新图中是点,点权为$w_i$,边权为两个字符串的LCP。

对字典树进行DFS,将每个点周围一圈边对应的字符串按DFS序从小到大排序。

根据后缀数组利用height数组求LCP的原理,类似地可以得到:

令$h_i=LCP(str_i,str_{i+1})$,则$LCP(str_l,str_r)=\min(h_{l..r-1})$。

枚举每个$h_i$作为分界线,那么新图中两侧的点均可以通过不超过$h_i$的代价互相访问。

建立一排前缀虚点和后缀虚点然后对应前后缀之间连边即可。

如此建图的点数和边数均为$O(m)$,时间复杂度$O(m\log m)$。

 

#include<cstdio>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
typedef pair<int,int>P;
const int N=50010,inf=~0U>>1;
int Case,n,m,K,i,j,x,y,z,g[N],nxt[N],size[N],f[N],d[N],son[N],loc[N],top[N],dfn;
int gi[N],go[N],V[N<<1],NXT[N<<1],ED;
int cnt,pi[N<<1],po[N<<1],si[N<<1],so[N<<1],cq,q[N<<1];
inline void read(int&a){char c;while(!(((c=getchar())>='0')&&(c<='9')));a=c-'0';while(((c=getchar())>='0')&&(c<='9'))(a*=10)+=c-'0';}
struct E{int a,b,c,d;}e[N];
namespace G{
const int N=450010,M=800010;
int g[N],v[M],w[M],nxt[M],ed,val[N],d[N];priority_queue<P,vector<P>,greater<P> >q;
inline void add(int x,int y,int z){v[++ed]=y;w[ed]=z;nxt[ed]=g[x];g[x]=ed;}
inline void ext(int x,int y){
  y+=val[x];
  if(y<d[x])q.push(P(d[x]=y,x));
}
void solve(){
  for(i=1;i<=cnt;i++)d[i]=inf;
  for(i=1;i<=m;i++)if(e[i].a==1)ext(i,0);
  while(!q.empty()){
    P t=q.top();q.pop();
    if(d[t.second]>t.first)continue;
    for(i=g[t.second];i;i=nxt[i])ext(v[i],t.first+w[i]);
  }
}
}
inline bool cmp(int x,int y){return loc[e[abs(x)].d]<loc[e[abs(y)].d];}
inline void add(int x,int y){nxt[y]=g[x];g[x]=y;}
inline void ADD(int&x,int y){V[++ED]=y;NXT[ED]=x;x=ED;}
void dfs(int x){
  size[x]=1;
  for(int i=g[x];i;i=nxt[i]){
    f[i]=x,d[i]=d[x]+1;
    dfs(i),size[x]+=size[i];
    if(size[i]>size[son[x]])son[x]=i;
  }
}
void dfs2(int x,int y){
  loc[x]=++dfn;top[x]=y;
  if(son[x])dfs2(son[x],y);
  for(int i=g[x];i;i=nxt[i])if(i!=son[x])dfs2(i,i);
}
inline int lca(int x,int y){
  for(;top[x]!=top[y];x=f[top[x]])if(d[top[x]]<d[top[y]])swap(x,y);
  return min(d[x],d[y]);
}
inline void solve(int x){
  int i;
  if(!gi[x]||!go[x])return;
  cq=0;
  for(i=gi[x];i;i=NXT[i])q[++cq]=V[i];
  for(i=go[x];i;i=NXT[i])q[++cq]=-V[i];
  sort(q+1,q+cq+1,cmp);
  for(i=1;i<=cq;i++){
    pi[i]=++cnt;
    si[i]=++cnt;
    po[i]=++cnt;
    so[i]=++cnt;
    if(i>1){
      G::add(pi[i-1],pi[i],0);
      G::add(po[i-1],po[i],0);
      G::add(si[i],si[i-1],0);
      G::add(so[i],so[i-1],0);
    }
    if(q[i]>0)G::add(q[i],pi[i],0),G::add(q[i],si[i],0);
    else q[i]*=-1,G::add(po[i],q[i],0),G::add(so[i],q[i],0);
  }
  for(i=1;i<cq;i++){
    int t=lca(e[q[i]].d,e[q[i+1]].d);
    G::add(pi[i],po[i+1],t);
    G::add(si[i+1],so[i],t);
  }
}
int main(){
  read(Case);
  while(Case--){
    read(n),read(m),read(K);
    for(i=1;i<=m;i++){
      read(e[i].a),read(e[i].b),read(e[i].c),read(e[i].d);
      ADD(gi[e[i].b],i),ADD(go[e[i].a],i);
      G::val[i]=e[i].c;
    }
    cnt=m;
    for(i=1;i<K;i++)read(x),read(y),read(z),add(x,y);
    dfs(1),dfs2(1,1);
    for(i=1;i<=n;i++)solve(i);
    G::solve();
    for(i=2;i<=n;i++){
      x=inf;
      for(j=gi[i];j;j=NXT[j])x=min(x,G::d[V[j]]);
      printf("%d\n",x);
    }
    for(i=1;i<=cnt;i++)G::g[i]=G::val[i]=0;
    for(i=1;i<=K;i++)g[i]=size[i]=f[i]=d[i]=son[i]=0;
    for(i=1;i<=n;i++)gi[i]=go[i]=0;
    ED=dfn=G::ed=0;
  }
  return 0;
}

相关文章

微信拍一拍创意搞笑后缀大全 拍了拍后缀文字怎么添加?

微信拍一拍创意搞笑后缀大全 拍了拍后缀文字怎么添加?

微信拍一拍创意后缀怎么设置?如何选择后缀的内容?拍一拍的后缀可以随意添加各种文字,不管是什么内容都可以,设置的方法和创意后缀的名字下面都有详细的攻略,是小编为大家搜集的各种新奇的拍一拍后缀哦! 微信...

微信拍一拍霸气后缀句子分享 微信拍一拍霸气的后缀内容推荐

微信拍一拍霸气后缀句子分享 微信拍一拍霸气的后缀内容推荐

微信拍一拍霸气的后缀有哪些?拍一拍的多功能后缀绝对是最好玩的,经常能玩出新花样,这次为大家带来的是霸气的拍一拍后缀,文案内容都会给大家分享在下面,各位玩家也都可以通过下面的内容掌握最新的霸气后缀文案。...

微信拍了拍搞笑后缀内容大全 微信拍一拍搞笑后缀怎么设置

微信拍了拍搞笑后缀内容大全 微信拍一拍搞笑后缀怎么设置

微信拍一拍搞笑后缀已经可以自定义了,很多朋友还不知道这个搞笑后缀要怎么设置才能最有效果,那么今天小编就为大家奉上一些搞笑后缀的参考,感兴趣的朋友们一起来看看吧,希望大家能够喜欢。 腾讯微信 iOS...

微信拍一拍怎么加后缀 后缀添加方法 微信拍一拍怎么设置详细方法

微信拍一拍怎么加后缀 后缀添加方法 微信拍一拍怎么设置详细方法

最近发现拍了拍后缀搞笑 教大家如何设置微信拍一拍设置搞笑后缀这话题成为了来自R.网友关注的焦点,小明对拍了拍后缀搞笑 教大家如何设置微信拍一拍设置搞笑后缀比较感兴趣,于是收集了一份相关资料供给大家更深...

微信拍一拍搞笑后缀怎么写 微信拍一拍后缀在哪里设置详细步骤

微信拍一拍后缀怎么写 在近期,微信上线了一个比较好玩的功能“拍一拍”,在该功能上线后有的小伙伴发现有人在拍自己后,会出现一串出了xx拍了拍你外,还有一段有趣后缀文字,那么这个文字后缀要怎么设置呢,赶...

微信拍了拍后面加一句话怎么设置?微信拍一拍创意后缀文案大全

微信拍了拍后面加一句话怎么设置?微信拍一拍创意后缀文案大全

微信拍了拍后面加一句话创意的设置方法是什么?在微信的哪里可以设置?这一点有很多人弄不清楚,特别是还没有改过后缀的小伙伴,小编今天不仅带来了加创意文字的方法,还有很多的创意后缀文案可以分享给大家哦。...