给定一个无向图和其中的所有边,判断这个图是否所有顶点都是连通的。要求输入每组数据的第一行是两个整数 n 和 m(0<=n<=1000)。n 表示图的顶点数目,m 表示图中边的数目。如果 n 为 0 表示输入结束。随后有 m 行数据,每行有两个值 x 和 y(0<x, y <=n),表示顶点 x 和 y 相连,顶点的编号从 1 开始计算。输入不保证这些边是否重复。输出对于每组输入数据,如果所有顶点都是连通的,输出"YES",否则输出"NO"。上述问题用C语言和数据结构的知识如何写代码
时间: 2023-12-10 20:39:46 浏览: 135
C语言 输入无向图连通图的顶点数、顶点信息、边数、顶点对序列及遍历的起始点序号,输出深度优先遍历序列
5星 · 资源好评率100%
可以使用并查集来解决此问题。
首先,我们定义一个数组 parent,用来存储每个顶点的父节点。初始时,每个顶点的父节点都是自己。
接下来,我们遍历每条边,如果两个顶点不在同一个集合中,就将它们合并为同一个集合。具体地,我们找到它们的根节点,然后将其中一个根节点的父节点指向另一个根节点。
最后,我们遍历所有顶点,如果发现有两个顶点的根节点不同,就说明这个图不是连通的。否则,就是连通的。
以下是 C 语言代码实现:
```c
#include <stdio.h>
#define MAX_N 1000
int parent[MAX_N + 1];
int find(int x) {
if (parent[x] == x) {
return x;
}
return parent[x] = find(parent[x]);
}
void merge(int x, int y) {
int root_x = find(x);
int root_y = find(y);
if (root_x != root_y) {
parent[root_x] = root_y;
}
}
int main() {
int n, m;
while (scanf("%d%d", &n, &m) == 2 && n > 0) {
// 初始化
for (int i = 1; i <= n; i++) {
parent[i] = i;
}
// 合并集合
for (int i = 0; i < m; i++) {
int x, y;
scanf("%d%d", &x, &y);
merge(x, y);
}
// 判断连通性
int root = find(1);
int connected = 1;
for (int i = 2; i <= n; i++) {
if (find(i) != root) {
connected = 0;
break;
}
}
// 输出结果
if (connected) {
printf("YES\n");
} else {
printf("NO\n");
}
}
return 0;
}
```
阅读全文