一开始给每个节点设立一个虚父节点,如果要删除一个点的关系,就直接把他的父亲改成一个新的点,这样就不会引起冲突了。
注意下面的mp数组需要开的跟f数组一样大,因为这个re了无数次,可能只有我会犯这么傻的错误吧(
我的表述可能不是很清楚
所以
转载解析:https://www.cnblogs.com/Alan-Luo/articles/9221408.html
1 #include<iostream> 2 #include<string.h> 3 using namespace std; 4 int n,m,f[1200005],idx,t=0; 5 bool mp[1200005]; 6 char op; 7 void ini(){ 8 for (int i=0;i<n;i++) f[i]=i+n; 9 for (int i=n;i<=n+m+n;i++) f[i]=i; 10 } 11 12 int getf(int u){ 13 return f[u]==u?f[u]:f[u]=getf(f[u]); 14 } 15 16 void merge(int u,int v){ 17 int uf=getf(u); 18 int vf=getf(v); 19 if (uf!=vf) f[uf]=vf; 20 } 21 22 void del(int u){ 23 f[u]=idx++; 24 } 25 26 int main(){ 27 while (cin>>n>>m){ 28 if (n==0 && m==0) break; 29 idx=n+n; 30 ini(); 31 while (m--){ 32 cin>>op; 33 int u,v; 34 if (op==‘M‘){ 35 scanf("%d %d",&u,&v); 36 merge(u,v); 37 } 38 else{ 39 scanf("%d",&u); 40 del(u); 41 } 42 } 43 int ans=0; 44 memset(mp,0,sizeof mp); 45 for (int i=0;i<n;i++){ 46 int tmp=getf(i); 47 if (!mp[tmp]){ 48 ans++; 49 mp[tmp]=1; 50 } 51 } 52 printf("Case #%d: %d\n", ++t, ans); 53 } 54 return 0; 55 }
原文:https://www.cnblogs.com/whiteli/p/12896657.html