在计算机科学中,并查集是一种树型的数据结构,其保持着用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。有一个联合-查找算法(union-find algorithm)定义了两个操作用于此数据结构:
- Find:确定元素属于哪一个子集。它可以被用来确定两个元素是否属于同一子集。
- Union:将两个子集合并成同一个集合。
并查集的三种基本操作:
①、初始化操作
void Initial()
{
for(int i = 0;i < 1010;i ++)
father[i] = i
}
②、Find操作
int getfather(int x)
{
if(father[x] == x) return x;
else
{
father[x] = getfather(father[x]);
return father[x];
}
}
③、Union操作
void Union(int x,int y)
{
int fx = getfather(x);
int fy = getfather(y);
if(fx != fy) father[fy] = fx;
}
以上为基本的操作.
hdu 1325判断是否为一棵树的问题。
1、空树也是树 2、树必须无环 3、森林不是树
# include <iostream>
# include <string>
using namespace std;
int father[1010];
int visit[1010];
bool flag;
void Initial()
{
flag = true;
for(int i = 0;i < 1010;i ++)
father[i] = i,visit[i] = 0;
}
int getfather(int x)
{
if(father[x] == x) return x;
else
{
father[x] = getfather(father[x]);
return father[x];
}
}
void Union(int x,int y)
{
int fx = getfather(x);
int fy = getfather(y);
if(fx != fy) father[fy] = fx;
}
bool judge()
{
int pre = -1;
for(int i = 0;i < 1010;i ++)
{
if(visit[i])
{
if(pre == -1) pre = getfather(i);
else
{
if(getfather(i) != pre) return false;
}
}
}
return true;
}
int main()
{
int a,b,cas = 1;
Initial();
while(cin>>a>>b)
{
if(a < 0 && b < 0) break;
else if(a == 0 && b == 0)
{
if(flag&&judge())cout<<"Case "<<cas<<" is a tree."<<endl;
else cout<<"Case "<<cas<<" is not a tree."<<endl;
cas ++;
Initial();
}
else
{
if(a == b) flag = false;
if(visit[b] == 1) flag = false;
visit[a] = visit[b] = 1;
Union(a,b);
}
}
return 0;
}
hdu 1232
思路:把每个镇的祖先储存的一个数组中,如果某个镇的祖先已经存在于这个数组中,那么就不添加,否则添加,最后获取添加的个数-1,就是所求。
# include <iostream>
# include <algorithm>
using namespace std;
int n,m;
int father[1010];
int ans[1010];
void Initial()
{
for(int i = 0;i < 1010;i ++)
father[i] = i;
}
int getfather(int x)
{
if(father[x] == x) return x;
else
{
father[x] = getfather(father[x]);
return father[x];
}
}
int getans()
{
int k = 0;
for(int i = 1;i <= n;i ++)
{
int num = getfather(i);
bool flag = true;
for(int j = 0;j < k;j ++)
{
if(num == ans[j])
{
flag = false;
break;
}
}
if(flag) ans[k] = num,k += 1;
}
return k-1;
}
void Union(int x,int y)
{
int fx = getfather(x);
int fy = getfather(y);
if(fx != fy) father[fx] = fy;
}
int main()
{
Initial();
while(cin >> n)
{
if(n == 0) break;
cin >> m;
for(int i = 0;i < m;i ++)
{
int a,b;
cin >> a >> b ;
Union(a,b);
}
cout<<getans()<<endl;
Initial();
}
return 0;
}