题目:点击打开链接
思路:
用并查集,判断是否有回路和是否全部连通。
空树(0 0)输出yes。
判断回路:
等等,其实没必要一定让大的作为父结点,连在一起就行,判断如果有相同父节点,说明有回路。
#include<bits/stdc++.h>
#define ll long long int
using namespace std;
const int N=100010;
int h[N];
bool vis[N];
int find(int x){
return h[x]==x?x:h[x]=find(h[x]);
}
void Union(int x,int y){
int a=find(x);
int b=find(y);
if(a==b)
return ;
h[a]=b;
}
int main(){
int m, n;
bool ok;
for(int i=1; i<=100000; i++) h[i] = i;
ok = true;
while(scanf("%d%d", &m, &n)&&m != -1 && n != -1) {
vis[m]=true; vis[n]=true;
int tmp;
if(m!=-1&&m!=0) tmp=m; //随便记录其中一个数。
if(m == 0 || n == 0) {
int temp=find(tmp),cnt=0;
for(int i=1;i<=100000;i++){
if(vis[i]&&find(i)!=temp)
cnt++;
}
if(cnt!=0) printf("No\n");
else printf(ok ? "Yes\n" : "No\n");
for(int i=1; i<=100000; i++) h[i] = i;
ok = true;
memset(vis,0,sizeof(vis));
} else {
if(find(m) == find(n)) ok = false;
else Union(m,n);
}
}
return 0;
}