Is It A Tree?(並查集)

Descriptionnode

A tree is a well-known data structure that is either empty (null, void, nothing) or is a set of one or more nodes connected by directed edges between nodes satisfying the following properties.

There is exactly one node, called the root, to which no directed edges point.
Every node except the root has exactly one edge pointing to it.
There is a unique sequence of directed edges from the root to each node.
For example, consider the illustrations below, in which nodes are represented by circles and edges are represented by lines with arrowheads. The first two of these are trees, but the last is not.

In this problem you will be given several descriptions of collections of nodes connected by directed edges. For each of these you are to determine if the collection satisfies the definition of a tree or not.

Inputide

The input will consist of a sequence of descriptions (test cases) followed by a pair of negative integers. Each test case will consist of a sequence of edge descriptions followed by a pair of zeroes Each edge description will consist of a pair of integers; the first integer identifies the node from which the edge begins, and the second integer identifies the node to which the edge is directed. Node numbers will always be greater than zero.

Outputthis

For each test case display the line "Case k is a tree." or the line "Case k is not a tree.", where k corresponds to the test case number (they are sequentially numbered starting with 1).

Sample Inputspa

6 8  5 3  5 2  6 4
5 6  0 0

8 1  7 3  6 2  8 9  7 5
7 4  7 8  7 6  0 0

3 8  6 8  6 4
5 3  5 6  5 2  0 0
-1 -1

Sample Outputcode

Case 1 is a tree.
Case 2 is a tree.
Case 3 is not a tree.


題目意思:判斷所給的數據可否構成一顆樹。

解題思路:題目中所給的是有向樹,並給出了性質:
1.只有一個節點,稱爲根節點,沒有定向邊指向它。
2.除了根節點外,每一個節點都只有有一條指向它的邊。
3.從樹根到任一結點有一條有向通路。
抽象過來就是三個條件:
1.只有一個入度爲0的點,做爲根節點。
2.除根節點外,其餘點的入度只能爲1。
3.全部點都能連通,也就是全部點須要在一個集合中,使用並查集來劃分集合。

注意!!!可能會出現空樹,也就是0 0,空樹也是樹。
 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;  5 const int MAX=1e4+10;  6 int pre[MAX];///並查集記錄父親節點
 7 int in[MAX];///入度
 8 int vis[MAX];///節點是否存在
 9 void init()  10 {  11     int i;  12     for(i=1; i<MAX; i++)  13  {  14         vis[i]=0;  15         in[i]=0;  16         pre[i]=i;  17  }  18 }  19 int Find(int x)  20 {  21     if(pre[x]==x)  22  {  23         return x;  24  }  25     else
 26  {  27         return Find(pre[x]);  28  }  29 }  30 void Union(int root1,int root2)  31 {  32     int x,y;  33     x=Find(root1);  34     y=Find(root2);  35     if(x!=y)  36  {  37         pre[x]=y;  38  }  39 }  40 int main()  41 {  42     int i,root,counts,a,b,flag,ans=1;  43     while(scanf("%d%d",&a,&b)!=EOF)  44  {  45         if(a==-1&&b==-1)  46  {  47             break;  48  }  49         if(a==0&&b==0)///空樹
 50  {  51             printf("Case %d is a tree.\n",ans);  52             ans++;  53             continue;  54  }  55  init();  56         vis[a]=1;  57         vis[b]=1;  58         in[b]++;  59  Union(a,b);  60         while(scanf("%d%d",&a,&b)!=EOF)  61  {  62             if(a==0&&b==0)  63  {  64                 break;  65  }  66             vis[a]=1;  67             vis[b]=1;  68             in[b]++;  69  Union(a,b);  70  }  71         flag=1;  72         root=0;  73         counts=0;  74         for(i=1;i<MAX;i++)  75  {  76             if(vis[i]&&in[i]==0)///根節點個數
 77  {  78                 root++;  79  }  80             if(in[i]>=2)///除根節點外,其餘點入度需爲1
 81  {  82                 flag=0;  83  }  84             if(vis[i]&&pre[i]==i)///全部點都在一個集合中
 85  {  86                 counts++;  87  }  88  }  89         if(root!=1||counts>1)  90  {  91             flag=0;  92  }  93         if(flag)  94  {  95             printf("Case %d is a tree.\n",ans);  96             ans++;  97  }  98         else
 99  { 100             printf("Case %d is not a tree.\n",ans); 101             ans++; 102  } 103  } 104     return 0; 105 }
相關文章
相關標籤/搜索