hdu1272 并查集

题意:给出一张无向图,问是否这张图中每两点之间有且只有一条路走。

除了输入烦一点……不是标准的输入的都是耍流氓……总之就是问这张图是否是一颗树,其实还是比较水的,用了并查集判连通,对于每一条边,如果相连两点已经连通,那么这条边就会造成这两点间有第二条路了,所以就可以判断不成立,合并时记录合并的次数,如果最后正好是 点数-1 次合并就说明符合要求。

 1 #include<stdio.h>
 2 #include<string.h>
 3 
 4 int fa[100005],n,vi[100005],cnt;
 5 
 6 int mmax(int a,int b){
 7     return a>b?a:b;
 8 }
 9 
10 void init(){
11     for(int i=1;i<=100004;i++)fa[i]=i;
12 }
13 
14 int find(int x){
15     int r=x,t;
16     while(r!=fa[r])r=fa[r];
17     while(x!=r){
18         t=fa[x];
19         fa[x]=r;
20         x=t;
21     }
22     return r;
23 }
24 
25 int main(){
26     int a,b;
27     while(scanf("%d%d",&a,&b)!=EOF&&a!=-1||b!=-1){
28         if(a==0&&b==0){
29             printf("Yes
");
30             continue;
31         }
32         init();
33         cnt=0;
34         memset(vi,0,sizeof(vi));
35         if(!vi[a]){
36             cnt++;
37             vi[a]=1;
38         }
39         if(!vi[b]){
40             cnt++;
41             vi[b]=1;
42         }
43         int x=find(a),y=find(b),ans=0;
44         bool f=1;
45         if(x!=y){
46             fa[x]=y;
47             ans++;
48         }
49         else f=0;
50         while(scanf("%d%d",&a,&b)&&a!=0||b!=0){
51             if(!vi[a]){
52                 cnt++;
53                 vi[a]=1;
54             }
55             if(!vi[b]){
56                 cnt++;
57                 vi[b]=1;
58             }
59             x=find(a),y=find(b);
60             if(x!=y){
61                 fa[x]=y;
62                 ans++;
63             }
64             else f=0;
65         }
66         if(ans==cnt-1&&f)printf("Yes
");
67         else printf("No
");
68     }
69     return 0;
70 }
View Code
原文地址:https://www.cnblogs.com/cenariusxz/p/4792973.html