标签:
8 13
0 1
1 6
6 5
5 0
0 6
1 2
2 3
3 4
4 5
7 1
7 2
7 6
3 6
5
1
6
3
5
7
1
1
1
2
3
3
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; int head[400001],next[400001],list[400001],a[400001],f[400001],ans[400001],n,m,k,sum,x,p,q,y,rest; bool visit[400001]; int read() { char c=getchar(); int a=0; while (c<‘0‘||c>‘9‘) c=getchar(); while (c>=‘0‘&&c<=‘9‘) { a=a*10+c-‘0‘; c=getchar(); } return a; } int find(int i) { int j=i,k=i,t; while (f[j]!=j) j=f[j]; while (f[k]!=k) { t=k; k=f[k]; f[t]=j; } return j; } void insert(int x,int y) { sum++; next[sum]=head[x]; head[x]=sum; list[sum]=y; } int main() { n=read(); m=read(); sum=0; for (int i=1;i<=m;i++) { x=read(); y=read(); insert(x,y); insert(y,x); } k=read(); memset(visit,1,sizeof(visit)); for (int i=1;i<=k;i++) { a[i]=read(); visit[a[i]]=0; } for (int i=0;i<n;i++) f[i]=i; rest=n-k; for (int i=0;i<n;i++) if (visit[i]) { x=head[i]; while (x!=0) { if (visit[list[x]]) if (find(i)!=find(list[x])) { f[find(i)]=find(list[x]); rest--; } x=next[x]; } } ans[k+1]=rest; for (int i=k;i>=1;i--) { visit[a[i]]=true; rest++; p=find(a[i]); x=head[a[i]]; while (x!=0) { if (visit[list[x]]) { q=find(list[x]); if (p!=q) { f[q]=p; rest--; } } x=next[x]; } ans[i]=rest; } for (int i=1;i<=k+1;i++) printf("%d\n",ans[i]); return 0; }
#2: Accepted (686ms, 10548KiB)
#3: Accepted (171ms, 10544KiB)
#5: Accepted (561ms, 10544KiB)
#7: Accepted (140ms, 10544KiB)
#8: Accepted (748ms, 10548KiB)
#9: Accepted (670ms, 10548KiB)
PS:
最好用非递归并查集。
规模较大,建议使用读入优化。
标签:
原文地址:http://www.cnblogs.com/ws-fqk/p/4392373.html