POJ 1308-Is It A Tree?(并查集)

xiaoxiao2021-02-27  453

Is It A Tree? Time Limit: 1000MS Memory Limit: 10000KTotal Submissions: 32343 Accepted: 10974

Description

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.

Input

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.

Output

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 Input

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 Output

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

Source

North Central North America 1997

题目意思:

给出若干组(a,b)表示一条有向边的起终点,求这些点能否构成一棵树。

解题思路:

①一棵树只有一个根结点; ②除了根节点以外的每一个节点都只有一条边指向它; ③不能出现环。 合并时注意:若b连到a上,则b要是根节点;同一棵树的两点不能再次合并。 用并查集对上述操作检验,合法操作合并,最后统计出现过的节点中构成的根节点数量。 #include <iostream> #include <cstring> #include <string> #include <vector> #include <queue> #include <cstdio> #include <algorithm> #include <queue> #include <iomanip> #include <map> #include <ctime> #define INF 0x3f3f3f3f #define MAXN 110 using namespace std; int fa[MAXN]; bool vis[MAXN]; int fa_find(int p) { if(fa[p]==p) return p; return fa[p]=fa_find(fa[p]); } bool join(int p,int q) { int p1=fa_find(p); int q1=fa_find(q); if(q1!=q) return true;//q不是根节点 if(p1==q1) return true;//p和q已经在同一棵树 else fa[q1]=p1;//合并两棵树 return false; } int main() { #ifdef ONLINE_JUDGE #else freopen("G:/cbx/read.txt","r",stdin); //freopen("G:/cbx/out.txt","w",stdout); #endif int n=0,a,b,ca=0,ans=0; for(int i=0; i<MAXN; ++i) fa[i]=i; memset(vis,false,sizeof(vis)); while(~scanf("%d%d",&a,&b)) { if(a==-1&&b==-1) break; if(a==0&&b==0) { int cnt=0; for(int i=0; i<n; i++) { if(fa[i]==i&&vis[i])//在出现过的节点中统计树根的数量 ++cnt; if(cnt>1) break; } if(cnt>1||ans>0)//多棵树或者出现过不合法的情况 cout<<"Case "<<++ca<<" is not a tree."<<endl; else cout<<"Case "<<++ca<<" is a tree."<<endl; ans=0;//初始化 for(int i=0; i<MAXN; ++i) fa[i]=i; memset(vis,false,sizeof(vis)); continue; } n=max(n,a); n=max(n,b);//记录最大的序号 vis[a]=vis[b]=true;//标记节点出现过 if(join(a,b)) ++ans;//出现不合法情况 } return 0; }
转载请注明原文地址: https://www.6miu.com/read-736.html

最新回复(0)