HDOJ 1308.Is It A Tree?

2015-07-15

问题简述:

  给出一组节点关系,判断由这些节点组成的图是否为一颗树。

  树只有一个根节点,每个节点只有一条边指向它,没有环。

  原题链接:http://poj.org/problem?id=1308

解题思路:

  使用并查集判断是否只有一个根节点是很简单的——让并查集种祖先的父亲是他自己即可方便计算其数量,一旦祖先数量超过一,它就不是树;

  也可使用并查集判断图是否有环——当两个即将要链接的节点都有相同的祖先时,这就产生了一个环。

源代码:

 1 /*
 2 OJ: HDOJ
 3 ID: forever
 4 TASK: 1308.Is It A Tree?
 5 LANG: C++
 6 NOTE: 并查集
 7 */
 8 #include <cstdio>
 9 
10 const int MAX=10005;
11 int father[MAX],sign[MAX],flag;
12 
13 int Find(int x) {
14     if(father[x]==x)
15         return x;
16     else
17         return Find(father[x]);
18 }
19 
20 void Union(int x,int y) {
21     x=Find(x);
22     y=Find(y);
23     if(x!=y)
24         father[x]=y;
25     else
26         flag=0;
27 }
28 
29 int main()
30 {
31     int a,b,k=1;
32     while(scanf("%d %d",&a,&b)) {
33         if(a==-1&&b==-1) break;
34         if(a==0&&b==0) {
35             printf("Case %d is a tree.
",k++);
36             continue;
37         }
38 
39         flag=1;
40         int m=0;
41         for(int i=0;i<MAX;i++) {
42             father[i]=i;
43             sign[i]=0;
44         }
45         Union(a,b);
46         sign[a]=sign[b]=1;
47 
48         while(scanf("%d %d",&a,&b)) {
49             if(a==0&&b==0) break;
50             if(a>m)
51                 m=a;
52             if(b>m)
53                 m=b;
54             Union(a,b);
55             sign[a]=sign[b]=1;
56         }
57         int sum=0;
58         for(int i=1;i<MAX;i++) {
59             if(sign[i]&&father[i]==i)
60                 sum++;
61             if(sum>1) {
62                 flag=0;
63                 break;
64             }
65         }
66         if(flag)
67             printf("Case %d is a tree.
",k++);
68         else
69             printf("Case %d is not a tree.
",k++);
70     }
71     return 0;
72 }
原文地址:https://www.cnblogs.com/ACMans/p/4647709.html