Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 22721 | Accepted: 7788 |
Description
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
Output
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.题目分析:
给你一些边,问你能不能构成一棵树。一棵树从一个节点到另一个节点,如果不走回头路的话只有一种路径。因此可将最初的点都看做来自不同的集合,每次都合并两个集合,合并前应先检测两个集合是否是同一个集合,若是同一个集合,则合并后和合并两点间将出现两条路径,故将不再是树。最后在遍历出现过的所有点,看这些点,是否都在同一个集合中,若不在说明是森林不是树。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int set[100005];
bool house[100005];
int find(int x) {
return set[x]==x?x:(set[x]=find(set[x]));
}
int main(){
int a,b,i,ca=1;
while(1){
for(i=1;i<100005;++i){
set[i]=i;house[i]=false;
}
scanf("%d%d",&a,&b);
if(a+b==-2) break;
if(a+b==0){
printf("Case %d is a tree.\n",ca++);
continue;
}
bool flag=true;
if(a!=b)
set[a]=b;
else
flag=false;
house[a]=house[b]=true;
while(scanf("%d%d",&a,&b),a){
house[a]=house[b]=true;
int fx=find(a),fy=find(b);
if(fx==fy) flag=false;
{
set[fx]=fy;
}
}
int cnt=0;
if(flag){
for(i=1;i<100005;++i){
if(house[i]){
if(set[i]==i)
++cnt;
}
}
if(cnt>1 || !cnt) flag=false;
}
printf("Case %d ",ca++);
if(flag) printf("is a tree.\n");
else printf("is not a tree.\n");
}
return 0;
}