POJ3694 Network 边双缩点+LCA+并查集
辣鸡错误:把dfs和ldfs搞混。。。QAQ
题意:给定一个无向图,然后查询q次,求每次查询就在图上增加一条边,求剩余割边的个数。
先把边双缩点,然后预处理出LCA的倍增数组;
然后加边时,从u往上跳,把所有u到LCA(u,v)路径上割边去掉,即 --ans;v同理;
而向上跳的时候可以用并查集,把已经去掉的边,用路径压缩忽略掉,会往上跳的更快些。
memset记得写全,不然。。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #define R register int 6 const int N=100010; 7 using namespace std; 8 inline int g() { 9 R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-1:fix; 10 do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; 11 } 12 int n,m,cc,cnt,num,dcc,T; 13 int vr[N<<2],nxt[N<<2],fir[N],dfn[N],low[N],c[N],d[N],f[N][18],fa[N]; 14 bool bge[N<<2]; 15 inline void add(int u,int v) {vr[++cnt]=v,nxt[cnt]=fir[u],fir[u]=cnt;} 16 void tarjan(int u,int E) { 17 dfn[u]=low[u]=++num; 18 for(R i=fir[u];i;i=nxt[i]) { R v=vr[i]; 19 if(!dfn[v]) { 20 tarjan(v,i); 21 low[u]=min(low[u],low[v]); 22 if(low[v]>dfn[u]) bge[i]=bge[i^1]=true; 23 } else if(i!=(E^1))low[u]=min(low[u],low[v]); 24 } 25 } 26 void dfs(int u) { 27 c[u]=dcc; 28 for(R i=fir[u];i;i=nxt[i]) if(!bge[i]&&!c[vr[i]]) dfs(vr[i]); 29 } 30 int ff[N],vv[N<<2],nn[N<<2],tc=1; 31 inline void addc(int u,int v) {vv[++tc]=v,nn[tc]=ff[u],ff[u]=tc;} 32 inline void solve() { 33 for(R i=2;i<=cnt;++i) { 34 R u=vr[i^1],v=vr[i]; 35 if(c[u]==c[v]) continue; 36 addc(c[u],c[v]); 37 } 38 } 39 void ldfs(int u) { 40 for(R i=ff[u];i;i=nn[i]) { R v=vv[i]; 41 if(d[v]) continue; 42 f[v][0]=u,d[v]=d[u]+1; R p=u; 43 for(R j=0;f[p][j];++j) f[v][j+1]=f[p][j],p=f[p][j]; 44 ldfs(v); 45 } 46 } 47 inline int lca(int u,int v) { 48 if(d[u]<d[v]) swap(u,v); R lim=log2(d[u])+1; 49 for(R i=lim;i>=0;--i) if(d[f[u][i]]>=d[v]) u=f[u][i]; 50 if(u==v) return u; 51 for(R i=lim;i>=0;--i) if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i]; 52 return f[u][0]; 53 } 54 int getf(int x) {return x==fa[x]?x:fa[x]=getf(fa[x]);} 55 signed main() { 56 while(n=g(),m=g(),m||n) { cnt=1;tc=1;num=dcc=cc=0; 57 memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(nxt,0,sizeof(nxt));memset(fir,0,sizeof(fir)); 58 memset(bge,false,sizeof(bge));memset(nn,0,sizeof(nn));memset(ff,0,sizeof(ff)); memset(c,0,sizeof(c));memset(f,0,sizeof(f)); 59 for(R i=1,u,v;i<=m;++i) u=g(),v=g(),add(u,v),add(v,u); 60 for(R i=1;i<=n;++i) if(!dfn[i]) tarjan(i,0); 61 for(R i=1;i<=n;++i) if(!c[i]) ++dcc,dfs(i); 62 for(R i=1;i<=n;++i) fa[i]=i; 63 solve(); d[1]=1;ldfs(1); R q=g(),ans=dcc-1; 64 printf("Case %d:\n",++T); 65 while(q--) { 66 R u=g(),v=g(); 67 u=c[u],v=c[v]; R L=lca(u,v); //cout<<L<<'\n'; 68 u=getf(u),v=getf(v); 69 while(d[u]>d[L]) fa[u]=f[u][0],--ans,u=getf(u); 70 while(d[v]>d[L]) fa[v]=f[v][0],--ans,v=getf(v); 71 printf("%d\n",ans); 72 } putchar('\n'); 73 } 74 }
2019.04.12