利用并查集实现,代码不难
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
#define N 1000 //元素的上限个数
int father[N]; //存储了每个元素父亲的下标
int height[N]; // 存储了某个根的高度
void Init(int n) {
//最开始时,每个元素单独构建一个集合
for (int i = 1; i <= n; i++) {
father[i] = i; //每个元素都是一个跟
height[i] = 1; //初始高度都为1
}
}
int Find(int x) {
if (x != father[x]) {
//递归向上查找
// find的路径压缩,找到祖先后不进行返回,而是设置成自己的父亲
father[x] = Find(father[x]); // 把链表上所有节点的父亲都改为祖先
}
return father[x];
}
void Union(int x, int y,int & num) {
//合并两棵树,合并y的祖先,把y的祖先的父亲设为x的祖先
// father[Find(y)] = Find(x);
x = Find(x);
y = Find(y);
if (x != y) { // x与y原本不属于同一个连通子图
--num; //减少连通子图的数量
}
if (height[x] < height[y]) { //判断两颗树的高度
father[x] = y;
}
else if (height[x] > height[y])
father[y] = x;
else { //两颗树高度相等
father[y] = x;
++height[x];
}
}
int main() {
int m, n;
while (cin >> n >> m) {
if (m == 0 && n == 0)
break;
Init(n); //初始化并查集
int num = n; //连通子图的数量
for (int i = 0; i < m; i++) {
int x, y;
cin >> x >> y;
Union(x, y,num);
}
if (num == 1) {
cout << "YES" << endl;
}
else cout << "NO" << endl;
}
}