在计算机科学中,并查集是一种树型的数据结构,其保持着用于处理一些不相交集合(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;
}
本文探讨了并查集数据结构的基本操作及其在判断树形结构问题中的应用,包括如何通过并查集判断树的存在性以及解决森林与树的概念区别。详细介绍了两种典型问题的解决方案,通过实例代码演示了并查集在实际编程中的应用。
1882

被折叠的 条评论
为什么被折叠?



