这道题几乎是并查集裸题。
就像 kruskal 建树一样,这道题也这么做。
但有两个很坑的细节:
1.测试数据可能给的不是一个连通图,因此最后要判一下所有点是否在同一集合中。
2.如果一组数据给的是空图,即只有 0,0 ,那么输出 yes 。
就这么多了。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=100010;
int fa[N];
bool vis[N];
int find(int x){
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
int main(){
int u,v,total; bool ok;
while(scanf("%d%d",&u,&v)==2 && ~u){
if(u==0 && v==0){ puts("Yes"); continue; } // 细节2
total=0;
for(int i=1; i<=100000; ++i) fa[i]=i, vis[i]=false;
fa[u]=v;
vis[u] = vis[v] = true;
ok=true;
while(scanf("%d%d",&u,&v)==2 && u) if(ok){
if(find(u)==find(v)){ ok=false; continue; }
fa[find(u)] = find(v);
vis[u] = vis[v] = true;
}
// 细节1
for(int i=1; i<=100000; ++i) if(vis[i] && fa[i]==i && (++total)>1){ ok=false; break; }
if(ok) puts("Yes");
else puts("No");
}
return 0;
}