标签:
#include<cstdio> #include<iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<cstring> #include<string> using namespace std; #define maxn 10005000 int pre[maxn],Rank[maxn]; // pre来存放集合,其中pre[i]中的i值是第i个元素,pre[i]的值是指i元素属于第pre[i]集合 void init (int n)// 初始化 大小为n { int i; for(i=0;i<n;i++) { pre[i]=i; Rank[i]=1; } } int find(int x) //寻找元素值为x的根节点 + 路径压缩 { int r; r=x; while(r!=pre[r]) r=pre[r]; int i=x,j; /*这是路径压缩,i一开始是x,然后j用来找上面的节点. 比如 1->2->3->4 (x=4)把4转化完时有: i=3;j=3; 状态为:1->2->3 1->4; 以此类推。 */ while(i!=r) { j=pre[i]; pre[i]=r; i=j; } return r; } void Union(int x,int y) //将x、y所在集合进行合并 { x=find(x); y=find(y); if(x==y) return ; //意思是,x和y的根节点一样,所以已经不需要合并了 if(Rank[x]>=Rank[y]) //如果x集合中元素个数大于或等于y集合 { pre[y]=x; //就把y放在x集合下面 Rank[x]+=Rank[y];//同时把x集合的元素个数增加rank[y]个 } else { pre[x]=y; Rank[y]+=Rank[x]; } return ; }
标签:
原文地址:http://www.cnblogs.com/ikids/p/4653498.html