判断两点:
1.任何2点的父节点不能相同->否则会导致2点间有多条通路
2.所有点只有1个集合
存在一个小坑,就是第一次输入 0 0 的时候,应该输出 Yes , 否则会WA
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; int root[100001]; int rank[100001]; int find(int x){ return root[x] == x ? x : (root[x] = find(root[x])); } void Union(int x, int y){ x = find(x); y = find(y); if(x == y) // x,y在同一个集合 return; if(rank[x] > rank[y]) root[y] = x; else if(rank[x] < rank[y]) root[x] = y; else{ rank[y]++; root[x] = y; } } int main(){ int n,m,t,x,y; int a,b,i; while(scanf("%d%d",&a,&b) , a+1 || b+1){ if(a == 0 && b == 0){ printf("Yes\n"); continue; } for(i=1; i<=100001; i++){ root[i] = i; rank[i] = 0; } int flag = 1;//flag表示是否有多条路 rank[a]++; rank[b]++; Union(a, b); while(scanf("%d%d",&a,&b) , a || b){ rank[a]++; rank[b]++; if(find(a) == find(b)) flag = 0; Union(a,b); } int cnt = 0;//cnt表示生成?个联通图 for(int i=1; i<=100001; ++i) if(rank[i] && find(i) == i)// cnt++; //printf("flag = %d cnt = %d\n",flag,cnt); if(flag && cnt == 1) printf("Yes\n"); else printf("No\n"); } return 0; }
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 23313 Accepted Submission(s): 7157
HDOJ 1272 并查集 不相同父节点,布布扣,bubuko.com
原文:http://www.cnblogs.com/wushuaiyi/p/3652744.html