poj1308 Is It A Tree?

并查集的基础题。在加入边前检查两点之前是否是同一个集合,若是则不是一棵树。输入完后检查是否所有点属于同一个集合。

 1 #include<cstdio>
 2 #include<string.h>
 3 #include<iostream>
 4 using namespace std;
 5 const int maxn=1<<15;
 6 bool flag,vis[maxn];
 7 int p[maxn],rank[maxn],data[maxn],m;
 8 int a,b,ra,rb;
 9 
10 int find(int x)
11 {
12     if(x!=p[x])
13     {
14         p[x]=find(p[x]);
15     }
16     return p[x];
17 }
18 
19 void unions(int x,int y)
20 {
21     if(rank[x]>rank[y])
22     {
23         p[y]=x;
24     }
25     else
26     {
27         p[x]=y;
28         if(rank[x]==rank[y])
29         rank[y]++;
30     }
31 }
32 int main()
33 {
34     //freopen("test.txt","r",stdin);
35     int t=0;
36     while(1)
37     {
38         flag=true;
39         m=0;
40         int i;
41         memset(vis,0,sizeof(vis));
42         for(i=1;i<=maxn;i++)
43         {
44             p[i]=i;
45             rank[i]=0;
46         }
47         while(scanf("%d%d",&a,&b)!=EOF)
48         {
49             if(a==-1&&b==-1) return 0;
50             if(a==0&&b==0)
51             {
52                 int key=find(data[0]);
53                 for(i=1;i<m;i++)
54                 {
55                     if(key!=find(data[i]))
56                     {
57                         flag=false;break;
58                     }
59                 }
60                 if(flag)
61                 printf("Case %d is a tree.\n",++t);
62                 else printf("Case %d is not a tree.\n",++t);
63                 break;
64             }
65             if(!vis[a]) {data[m++]=a;vis[a]=true;}
66             if(!vis[b]) {data[m++]=b;vis[b]=true;}
67             if(!flag) continue;
68             ra=find(a);
69             rb=find(b);
70             if(ra==rb) {flag=false;continue;}
71             unions(ra,rb);
72         }
73     }
74     return 0;
75 }
View Code
原文地址:https://www.cnblogs.com/longlongagocsu/p/3130982.html