学习并查集跟着视频走,看看我自己学了啥。
配合这位大佬的bilibili视频饮用更爽哟(有超链接)
题目大概就是判断这个图是否是闭环,是否是开环。

用并查集的方法。
(这些天,力扣的题好多都是并查集,实在是头痛)
代码如下,其中每步都差不多有介绍。希望能看懂,早日摆脱并查集的困扰(搞得像我自己也摆脱了一样)(代码没有错)
- 刚开始定义的GOD是上面图中有6个
- rank是树的长度,为了减少可能存在的树的长度爆炸问题
- 这个assignment函数是为了让数组里的每个数都重置,本人英语不好……莫怪
- 这find_root函数是为了寻找数的根节点
- union_vertries这个函数就是合并根节点了
- 上面说的几个函数在并查集里都是通用的
#include <stdio.h>
#define GOD 6 //从上面图上你也能看出是六个数,自然要设置为6
int assignment(int parent[],int rank[]//这个rank是为了减少可能存在的树的长度爆炸)
{
int i;
for(i = 0;i<GOD;i++)
parent[i] = -1;
rank[i] = 0;
}//本函数是重置数值
int find_root(int x,int parent[])//这个函数是为了寻找每个数的根节点
{
int x_root;
x_root = x;
while(x_root != -1)//因为刚开始定义的就是每个数都是-1
{
x_root = parent[x_root];
}
return x_root;
}
int union_vertries(int x,int y,int parent[],int rank[])
{//union是合并的意思,所以,这就是合并根节点的时候了。其中rank就是减少树长度的。
int x_root = find_root(x,parent);//寻找根节点
int y_root = find_root(y,parent);
if(x_root == y_root)
{
return 0;
}
else//这里是为了缩小运行。通过rank的大小判断树的高低
{
if(rank[x_root]>rank[y_root])
{
parent[y_root] = x_root;
}
else if(rank[x_root]<rank[y_root])
{
parent[x_root] = y_root;
}
else
{//如果两个树长度相等,随便连接就行,不过长度还要+1
parent[x_root] =y_root;
rank[y_root]++;
}
return 1;
}
}
int main()
{
int parent[GOD] = {0};
int rank[GOD] = {0};
assignment(parent,rank);//看完上面的函数,下面的式子自动带入就行
int edge[6][2] = {
{0,1},{1,2},{1,3},
{2,4},{2,5},{3,4}
};
int i;
for(i = 0;i<GOD;i++)
{
int x,y;
x = edge[i][0];
y = edge[i][1];
if(union_vertries(x,y,parent,rank) == 0)
{
printf("Cycle detected!\n");
exit(0);
}
}
printf("No cycle detected!\n");
return 0;
}
所以答案就是闭环的。希望能对大家有所帮助
本文通过并查集算法解决图的闭环检测问题,提供了一个C语言实现的例子,并详细解释了并查集中的关键函数如find_root和union_vertries的作用。

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



