利用并查集实现,代码不难 #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; } }