3237: [Ahoi2013]连通图
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 1736 Solved: 655
[Submit][Status][Discuss]Description
Input
Output
Sample Input
4 5
1 2
2 3
3 4
4 1
2 4
3
1 5
2 2 3
2 1 2Sample Output
Connected
Disconnected
ConnectedHINT
N<=100000 M<=200000 K<=100000
Source
在线LCT,离线CDQ。
考虑怎么使用CDQ,对于区间[L,R],先将不在[L,mid]而在[mid+1,R]中的边加入,递归到左半边,撤销,将不在[mid+1,R]而在[L,mid]中的边加入,再次递归,撤销。
一般带撤销并查集是不能路径压缩的,但其实压缩了也没关系,记录压缩之前的父亲就好。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define rep(i,l,r) for (int i=l; i<=r; i++) 5 typedef long long ll; 6 using namespace std; 7 8 const int N=200100,M=5000100; 9 struct P{ int u,v,tim; }e[N]; 10 struct Q{ int c[5],cnt; }q[N]; 11 int top,n,m,T,tim,u,v,f[N],ans[N],stk1[M],stk2[M]; 12 13 int find(int x){ 14 if (f[x]==x) return x; 15 int y=find(f[x]); 16 if (y!=f[x]) stk1[++top]=x,stk2[top]=f[x],f[x]=y; 17 return y; 18 } 19 20 void solve(int l,int r){ 21 int Top=top; 22 if (l==r){ 23 int flag=1; 24 rep(i,1,q[l].cnt) 25 if (find(e[q[l].c[i]].u)!=find(e[q[l].c[i]].v)) 26 { flag=0; break; } 27 ans[l]=flag; 28 while (top!=Top) f[stk1[top]]=stk2[top],top--; 29 return; 30 } 31 int mid=(l+r)>>1; tim++; 32 rep(i,l,mid) rep(j,1,q[i].cnt) e[q[i].c[j]].tim=tim; 33 rep(i,mid+1,r) rep(j,1,q[i].cnt){ 34 int x=q[i].c[j]; 35 if (e[x].tim!=tim){ 36 int u=find(e[x].u),v=find(e[x].v); 37 if (u!=v) stk1[++top]=u,stk2[top]=f[u],f[u]=v; 38 } 39 } 40 solve(l,mid); tim++; 41 while (top!=Top) f[stk1[top]]=stk2[top],top--; 42 rep(i,mid+1,r) rep(j,1,q[i].cnt) e[q[i].c[j]].tim=tim; 43 rep(i,l,mid) rep(j,1,q[i].cnt){ 44 int x=q[i].c[j]; 45 if (e[x].tim!=tim){ 46 int u=find(e[x].u),v=find(e[x].v); 47 if (u!=v) stk1[++top]=u,stk2[top]=f[u],f[u]=v; 48 } 49 } 50 solve(mid+1,r); 51 } 52 53 int main(){ 54 freopen("bzoj3237.in","r",stdin); 55 freopen("bzoj3237.out","w",stdout); 56 scanf("%d%d",&n,&m); tim=1; 57 rep(i,1,m) scanf("%d%d",&e[i].u,&e[i].v); 58 scanf("%d",&T); 59 rep(i,1,T){ 60 scanf("%d",&q[i].cnt); int x; 61 rep(j,1,q[i].cnt) scanf("%d",&x),q[i].c[j]=x,e[x].tim=tim; 62 } 63 rep(i,1,n) f[i]=i; 64 rep(i,1,m) if (e[i].tim!=tim){ 65 int u=find(e[i].u),v=find(e[i].v); 66 if (u!=v) f[u]=v; 67 } 68 solve(1,T); 69 rep(i,1,T) if (ans[i]) puts("Connected"); else puts("Disconnected"); 70 return 0; 71 }
原文地址:https://www.cnblogs.com/HocRiser/p/8983151.html
时间: 2024-10-06 10:58:05