bzoj1015 [JSOI2008]星球大战starwar
机智的倒序操作
+并查集离线处理
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<string> 5 #include<cstring> 6 #include<cmath> 7 #include<algorithm> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 using namespace std; 14 int ed=1,n,m,d,fa[400040],head[400040],q[400040],ans[400040]; 15 int sum,bo[400040],dis[400040],next[400040],zhi[400040]; 16 int find(int x) 17 { 18 return x==fa[x]?x:fa[x]=find(fa[x]); 19 } 20 inline int getint() 21 { 22 int f=1,ret=0; 23 char ch=getchar(); 24 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 25 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 26 return f==-1?-ret:ret; 27 } 28 void add(int a,int b) 29 { 30 next[++ed]=head[a],head[a]=ed,zhi[ed]=b; 31 next[++ed]=head[b],head[b]=ed,zhi[ed]=a; 32 } 33 void hh(int x) 34 { 35 int xx=find(x),q; 36 for(int i=head[x];i;i=next[i]) 37 if(bo[zhi[i]]) 38 { 39 q=find(zhi[i]); 40 if(xx!=q)fa[q]=xx,sum--; 41 } 42 } 43 int main() 44 { 45 n=getint(),m=getint(); 46 for(int i=0;i<n;i++)fa[i]=i; 47 for(int i=1;i<=m;i++) 48 { 49 int q,w; 50 q=getint(),w=getint(); 51 add(q,w); 52 } 53 d=getint(); 54 for(int i=1;i<=d;i++) 55 { 56 q[i]=getint(); 57 dis[q[i]]=1; 58 } 59 for(int i=0;i<n;i++) 60 if(!dis[i])sum++,hh(i),bo[i]=1; 61 ans[d+1]=sum; 62 for(int i=d;i>=0;i--) 63 sum++,hh(q[i]),bo[q[i]]=1,ans[i]=sum; 64 for(int i=1;i<=d+1;i++)printf("%d\n",ans[i]); 65 return 0; 66 }