图论——并查集(二):连通图
发布日期:2021-05-10 06:36:45 浏览次数:22 分类:精选文章

本文共 1726 字,大约阅读时间需要 5 分钟。

Introduction to Connected Components in Graphs

在图论中,连通分量、连通支路和极大连通子图是核心概念。无向图G的任何一个极大连通子图都被称为G的连通分量(或连通支路)。而如果一个图是有向图并且每两个顶点都是强连通的(即需要双向路径),则该图被称为一个强连通图。

Sample Use Case

给定一个无向图及其所有边,判断这个图是否所有顶点都是连通的。这个问题可以通过并查集(Union-Find)算法来高效解决。如果最终连通分量等于1,那么图就是一个连通图。

以下是实现这一功能的代码示例:

#include 
#include
using namespace std;
#define MAXN 1000
int father[MAXN];
int height[MAXN];
void Initialize(int n) {
for (int i = 0; i <= n; ++i) {
father[i] = i;
height[i] = 0;
}
}
int Find(int x) {
if (x != father[x]) {
father[x] = Find(father[x]);
}
return father[x];
}
void Union(int x, int y) {
x = Find(x);
y = Find(y);
if (x != y) {
if (height[x] < height[y]) {
father[x] = y;
} else if (height[y] < height[x]) {
father[y] = x;
} else {
father[y] = x;
height[x]++;
}
}
}
int main() {
int n, m;
while (scanf("%d", &n) != EOF) {
if (n == 0) {
break;
}
scanf("%d", &m);
Initialize(n);
for (int i = 0; i < m; ++i) {
int x, y;
scanf("%d %d", &x, &y);
Union(x, y);
}
int component = 0;
for (int i = 1; i <= n; ++i) {
if (Find(i) == i) {
component++;
}
}
if (component == 1) {
printf("YES\n");
} else {
printf("NO\n");
}
}
return 0;
}

Explanation

  • 初始化:首先,Initialize函数将每个节点的父节点设为自身,树的高度初始化为0。
  • 查找函数Find函数用于递归查找节点的根节点,通过路径压缩优化查找速度。
  • 合并函数Union函数用于将两棵树合并,具体策略是按照树的高度进行合并,确保高度平衡。
  • 主函数:读取输入数据,初始化并查集结构,处理每条边,进行合并操作,最后统计连通分量数量来判断图的连通性。
  • 这个并查集实现高效地处理了连通分量问题,确保了连通图的判断能够在合理时间内完成。

    上一篇:图论——并查集(三):判断是否为树
    下一篇:图论——并查集(一):并查集(Union Find)

    发表评论

    最新留言

    能坚持,总会有不一样的收获!
    [***.219.124.196]2025年04月15日 02时13分11秒