#include using namespace std; const int N = 1010; //图的最大点数量 /** 共提供两组数据,样例1为不连通用例,样例2为连通用例 样例1:不连通,5号结点为独立的 5 4 1 2 2 3 3 4 1 4 样例2:连通,不存在独立结点 5 4 1 2 2 3 3 4 1 5 检测各种算法是否能准确获取结果 */ int n; //n个人 int m; //m个亲戚 int p; //询问p对亲戚关系 int x, y; //输入两个人之间的关系 int fa[N]; //并查集数组 //要深入理解这个递归并压缩的过程 int find(int x) { if (fa[x] != x)//如果x不是族长,递归找父亲,副产品就是找回的结果更新掉自己的家族信息。 fa[x] = find(fa[x]);//非常经典的更新,路径压缩大法! //返回族长是谁 return fa[x]; } //加入家族集合中 void join(int c1, int c2) { int f1 = find(c1), f2 = find(c2); if (f1 != f2)fa[f1] = f2;//各自找家长,如果家长不一样,就把C1的族长,认C2的族长为爸爸,C1的族长强烈表示不满意 } int cnt; int main() { //n个人员,m个关系 cin >> n >> m; //并查集初始化 for (int i = 1; i <= n; i++)fa[i] = i; //自己是自己的老大 //录入m种关系,使用并查集来判断图的连通性 for (int i = 1; i <= m; i++) { cin >> x >> y; //加入并查集 join(x, y); } //图已经搭好了,接下来看它们根节点是否相同,如只有一个相同的根节点,则说明是一个连通图 for (int i = 1; i <= n; i++) if (fa[i] == i)cnt++; if (cnt == 1)printf("图是连通的\n"); else printf("图不是连通的\n"); return 0; }