(抄知识点方便自己复习)//摘自俞勇的acm国际大学生程序设计竞赛,知识与入门
基本概念
不相交集为一组彼此不相交(没有公共元素)的集合。并查集算法作用于一个不相交集,实际应用中可以在近乎常数的时间内完成下列两种操作。
1:查找(find):确定元素所在的集合。一般用来判断两个元素是否在同一个集合。
2:合并(Union):将两个集合合并成一个集合。
对于查找操作,假设需要确定x所在的集合,也就是确定集合的代表元。可以沿着parent【x】不断在树形结构中向上移动,直到到达根节点,根节点即代表元。
判断两个元素是否属于同一个集合,只需看他们的代表元是否相同即可。为了加快速度,每次查找操作的过程中,可以将x到根节点路径上的所有点的parent设为根节点,
这样下次再次查找时就不必再沿着路径一步步寻找了,该优化方法为压缩路径。
//hdu1988 带权并查集
#include <iostream>
using namespace std;
const int maxn=30005;
int fa[maxn],d[maxn],s[maxn];
int find(int x){
if(fa[x]==x)
return x;//若是根节点就直接返回
int t=fa[x];//否则记录点x的当前根节点。
fa[x]=find(fa[x]);//更新元。
d[x]+=d[t];//将其父节点的深度跟新跟x;
return fa[x];
}
void Move(int x,int y){
x=find(x),y=find(y);//找到对应的元
fa[x]=y;//跟新x的根节点
d[x]+=s[y];//更新其x的深度,y的树的大小,x树的大小。
s[y]+=s[x];
s[x]=0;
}
int main()
{
for(int i=0;i<maxn;i++){
fa[i]=i;
s[i]=1;
d[i]=0;
}
int p;
cin>>p;
while(p--){
char str[1];int a[2];
cin>>str[0];
if(str[0]=='M'){
cin>>a[0]>>a[1];
Move(a[0],a[1]);
}
if(str[0]=='C'){
cin>>a[0];
find(a[0]);
cout<<d[a[0]]<<endl;
}
}
//cout << "Hello world!" << endl;
return 0;
}
hdu 2492
http://blog.csdn.net/lxmky/article/details/7654916#//摘自
#include <iostream>
#include <cstring>
using namespace std;
const int maxn=5005;
int f[maxn],relations[maxn];
int find(int x){
int temp=f[x];
if(f[x]==x)
return x;
x=find(temp);
relations[x]=(relations[x]+relations[f[temp]])%2;
return f[x];
}
void unionset(int a,int b){
int x=find(a);int y=find(b);
if(x==y)
return ;
f[x]=y;
relations[x]=(relations[a]-relations[b]+1)%2;
return ;
}
int main()
{
int t,count=1;
cin>>t;
while(t--){
int n,m;
cin>>n>>m;
memset(relations,0,sizeof(relations));
for(int i=1;i<=n;i++){
f[i]=1;
}
int flag = 1;
for(int i = 0; i < m; i++)
{
int tmp1,tmp2;
cin>>tmp1>>tmp2;
if(find(tmp1) == find(tmp2))
{
if(relations[tmp1] != (relations[tmp2] + 1) % 2) //如果不满足异性关系,有矛盾
flag = 0;
}
else
{
unionset(tmp1, tmp2);
}
}
if(flag)
{
cout<<"Scenario #"<<count<<":"<<endl<<"No suspicious bugs found!"<<endl<<endl;
}
else
{
cout<<"Scenario #"<<count<<":"<<endl<<"Suspicious bugs found!"<<endl<<endl;
}
}
//cout << "Hello world!" << endl;
return 0;
}