[bzoj1969] [Ahoi2005]LANE 航线规划
tarjan、并查集、树状数组、树链剖分。
时间倒流,变删边为加边。
先求一波边双联通分量,缩点。
题目保证最后还是整张图联通的。。所以就是一棵树。
现在的操作就是,将路径上的边权置0(加边时),查询两点间边权和。
可以转换成求根到点路径上边权和,置0的时候,就相当于将子树内的值都减去原边的长度,可以dfs序+树状数组。
置0那个还要写个并查集,维护当前点经过连续一段0边到达的最远的祖先。
查询的时候还得求lca。。。。就顺便写个链剖...
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #define ui unsigned int 6 using namespace std; 7 const int maxn=30023,maxm=100023; 8 struct zs{int too,pre;}e[maxm<<1];int tot,last[maxn]; 9 bool iscut[maxm<<1]; 10 struct zs1{int x,y;}a[maxm]; 11 struct zs2{bool del;int id,x,y;}b[40023]; 12 int fa[maxn],bel[maxn],dep[maxn],dfn[maxn],low[maxn],tim,L[maxn],R[maxn],TIM,sz[maxn],cha[maxn],id[maxn]; 13 int la[maxn<<1],pre[maxn<<1],too[maxn<<1],tt; 14 int An[40023]; 15 int i,j,k,n,m,q,cnt; 16 bool gg[maxm]; 17 18 int ra,fh;char rx; 19 inline int read(){ 20 rx=getchar(),ra=0,fh=1; 21 while((rx<'0'||rx>'9')&&rx!='-')rx=getchar(); 22 if(rx=='-')fh=-1,rx=getchar(); 23 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra*fh; 24 } 25 26 inline int getbel(int x){return bel[x]!=x?bel[x]=getbel(bel[x]):x;} 27 28 void dfs(int x,int efa){ 29 dfn[x]=low[x]=++tim; 30 for(int i=last[x];i;i=e[i].pre)if(i!=efa) 31 if(!dfn[e[i].too]) 32 dfs(e[i].too,i^1),low[x]=min(low[x],low[e[i].too]); 33 else low[x]=min(low[x],dfn[e[i].too]); 34 if(dfn[x]==low[x]&&efa)iscut[efa]=iscut[efa^1]=1; 35 } 36 void dfs2(int x){ 37 dep[x]=dep[fa[x]]+1,sz[x]=1; 38 for(int i=la[x];i;i=pre[i]) 39 if(too[i]!=fa[x])fa[too[i]]=x,dfs2(too[i]),sz[x]+=sz[too[i]]; 40 } 41 void dfs3(int x,int chain){ 42 cha[x]=chain,L[x]=++TIM; 43 int i,mx=0; 44 for(i=la[x];i;i=pre[i])if(too[i]!=fa[x]&&sz[too[i]]>sz[mx])mx=too[i]; 45 if(!mx){R[x]=TIM;return;} 46 dfs3(mx,chain); 47 for(i=la[x];i;i=pre[i])if(too[i]!=fa[x]&&too[i]!=mx)dfs3(too[i],too[i]); 48 R[x]=TIM; 49 } 50 inline int getlca(int a,int b){ 51 while(cha[a]!=cha[b]){ 52 if(dep[cha[a]]<dep[cha[b]])swap(a,b); 53 a=fa[cha[a]]; 54 } 55 return dep[a]<dep[b]?a:b; 56 } 57 inline void insert(int a,int b){ 58 e[++tot].too=b,e[tot].pre=last[a],last[a]=tot, 59 e[++tot].too=a,e[tot].pre=last[b],last[b]=tot; 60 } 61 inline void ins(int a,int b){//printf(" %d-->%d\n",a,b); 62 too[++tt]=b,pre[tt]=la[a],la[a]=tt, 63 too[++tt]=a,pre[tt]=la[b],la[b]=tt; 64 } 65 int t[maxn]; 66 inline void add(int l,int r,int v){//printf(" add: %d--%d v:%d\n",l,r,v); 67 while(l<=cnt)t[l]-=v,l+=l&-l; 68 r++;while(r<=cnt)t[r]+=v,r+=r&-r; 69 } 70 inline int ask(int x){/*printf("__x: %d\n",x);*/int sm=0;while(x)sm+=t[x],x-=x&-x;return sm;} 71 72 inline int query(int x,int y){ 73 int lca=getlca(x,y);//printf("query: %d %d lca:%d %d %d\n",x,y,lca,getbel(x),getbel(y)); 74 x=dep[x]+ask(L[x]),y=dep[y]+ask(L[y]),lca=dep[lca]+ask(L[lca]);//printf("dep: %d %d %d\n",x,y,lca); 75 return x+y-(lca<<1); 76 } 77 inline void link(int x,int y){//printf("link:%d %d\n",x,y); 78 int i,j,tmp; 79 i=getbel(x),j=getbel(y);//printf(" %d %d dep:%d %d\n",i,j,dep[i],dep[j]); 80 while(i!=j){ 81 if(dep[i]<dep[j])swap(i,j); 82 tmp=getbel(fa[i]); 83 add(L[i],R[i],1/*dep[i]-dep[tmp]*/);//printf("i:%d tmp:%d\n",i,tmp); 84 bel[i]=tmp,i=bel[i]; 85 } 86 } 87 88 89 bool cmp(zs1 a,zs1 b){return a.x<b.x||(a.x==b.x&&a.y<b.y);} 90 inline int getpos(int x,int y){ 91 int l=1,r=m,mid; 92 while(l<r) 93 if(a[(mid=l+r>>1)].x==x?(a[mid].y==y?gg[mid]:a[mid].y<y):a[mid].x<x)l=mid+1;else r=mid; 94 return l; 95 } 96 int main(){ 97 n=read(),m=read();register int i; 98 for(i=1;i<=m;i++){ 99 j=read(),k=read(); 100 if(j>k)swap(j,k); 101 a[i].x=j,a[i].y=k; 102 } 103 sort(a+1,a+1+m,cmp); 104 int id1;i=0; 105 for(id1=read();id1!=-1;id1=read()){ 106 i++,j=b[i].x=read(),k=b[i].y=read(); 107 if(j>k)swap(j,k); 108 if(!id1)b[i].del=1,gg[b[i].id=getpos(j,k)]=1; 109 }q=i; 110 111 tot=1; 112 for(i=1;i<=m;i++)if(!gg[i])insert(a[i].x,a[i].y); 113 dfs(1,0); 114 for(i=1;i<=n;i++)bel[i]=i; 115 for(i=2;i<=tot;i+=2)if(!iscut[i]) 116 bel[getbel(e[i].too)]=getbel(e[i^1].too); 117 for(i=1;i<=n;i++)if(getbel(i)==i)id[i]=++cnt; 118 for(i=1;i<=q;i++){ 119 if(b[i].del)a[b[i].id].x=id[bel[a[b[i].id].x]],a[b[i].id].y=id[bel[a[b[i].id].y]]; 120 b[i].x=id[getbel(b[i].x)],b[i].y=id[getbel(b[i].y)]; 121 } 122 for(i=2;i<=tot;i+=2)if(iscut[i])ins(id[bel[e[i].too]],id[bel[e[i^1].too]]); 123 for(i=1;i<=cnt;i++)bel[i]=i; 124 fa[1]=0,dfs2(1),dfs3(1,1); 125 // for(i=1;i<=cnt;i++)printf(" i:%d dfn:%d bel:%d L:%d R:%d dep:%d\n",i,L[i],cha[i],L[i],R[i],dep[i]); 126 127 for(i=q;i;i--)//{ 128 if(!b[i].del)An[i]=query(b[i].x,b[i].y); 129 else link(a[b[i].id].x,a[b[i].id].y); 130 // for(j=1;j<=n;j++)printf(" %d",ask(j));puts(""); 131 // } 132 for(i=1;i<=q;i++)if(!b[i].del)printf("%d\n",An[i]); 133 } 134