hdu2473之并查集

来源:互联网 发布:淄博网络推广 编辑:程序博客网 时间:2024/06/05 16:54

思路:每次删除一个点a,并不把a从当前集合删除,而是用一个数组node[a]代表a对应的点,所以每次删除a后,node[a]=++n,即开辟一个新的点作为a对应的点,这样就不会影响a这个集合

http://acm.hdu.edu.cn/showproblem.php?pid=2473

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<map>#include<iomanip>#define INF 99999999using namespace std;const int MAX=100000+10;int father[MAX+MAX*10],rank[MAX+MAX*10],node[MAX],sum;void makeset(int num){for(int i=0;i<=num;++i){father[i]=i;rank[i]=1;}}int findset(int v){if(v != father[v])father[v]=findset(father[v]);return father[v];}void Union(int x,int y){int a=findset(x);int b=findset(y);if(a == b)return;if(rank[a]>rank[b]){father[b]=a;rank[a]+=rank[b];}else{father[a]=b;rank[b]+=rank[a];}--sum;}bool Delete(int x){int a=findset(x);if(rank[a]>1){++sum;--rank[a];return true;}return false;} int main(){int n,m,a,b,num=0;char s;while(scanf("%d%d",&n,&m),n+m){makeset(n+m);for(int i=0;i<=n;++i)node[i]=i;sum=n;for(int i=0;i<m;++i){getchar();scanf("%c",&s);if(s == 'M'){scanf("%d%d",&a,&b);Union(node[a],node[b]);}else{scanf("%d",&a);if(Delete(node[a]))node[a]=++n;//开辟新点作为a对应的点 }} printf("Case #%d: %d\n",++num,sum);}return 0;} 


 

原创粉丝点击