Is It A Tree?
TimeLimit: 2000/1000 MS (Java/Others) Memory Limit:65536/32768 K (Java/Others)
Total Submission(s): 28477 Accepted Submission(s): 6569
ProblemDescription
A tree isa well-known data structure that is either empty (null, void, nothing) or is aset of one or more nodes connected by directed edges between nodes satisfyingthe 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 representedby circles and edges are represented by lines with arrowheads. The first two ofthese are trees, but the last is not.
In this problem you will be given several descriptions of collections of nodesconnected by directed edges. For each of these you are to determine if thecollection satisfies the definition of a tree or not.
Input
The input will consist of a sequence ofdescriptions (test cases) followed by a pair of negative integers. Each testcase will consist of a sequence of edge descriptions followed by a pair ofzeroes Each edge description will consist of a pair of integers; the first integeridentifies the node from which the edge begins, and the second integeridentifies the node to which the edge is directed. Node numbers will always begreater than zero.
Output
For each test case display the line ``Casek is a tree." or the line ``Case k is not a tree.", where kcorresponds to the test case number (they are sequentially numbered startingwith 1).
SampleInput
6 8 5 35 2 6 4
5 6 0 0
8 1 7 36 2 8 9 7 5
7 4 7 87 6 0 0
3 8 6 86 4
5 3 5 65 2 0 0
-1 -1
SampleOutput
Case 1 isa tree.
Case 2is a tree.
Case 3is not a tree.
Source
NorthCentral North America 1997
Recommend
Ignatius.L | Wehave carefully selected several similar problems for you: 1272 1856 1213 1233 1875
算法分析:
第一种算法:
1,无环;
2,除了根,所有的入度为1,根入度为0;
3,这个结构只有一个根,不然是森林了。
再注意这里空树也是树,且1 1 0 0 不是树(不过HDU不管)
代码一看就明白
第二种算法:
1,无环;
2,结构只有一个根,不然是森林了。
并查集思想,保存根
代码实现:
#include<bits/stdc++.h>
using namespace std;
int fa[100005];
int main()
{
int a,b,flag,i,j;
int t=1;
while(1)
{
j=0;
i=0;
flag=0;
memset(fa,0,sizeof(fa));
while(scanf("%d%d",&a,&b)&&a&&b)
{
if(a==b) flag=1;
if(a<0||b<0)
return 0;
if(fa[b]-1==1)//判断是否有回路
flag=1;
if(fa[a]==0)
j++;
if(fa[b]==0)
j++;
fa[a]=1;fa[b]=2;i++;
}
if(flag==0&&j==i+1)//n个点组成一个树,则点的个数=边的个数加一
printf("Case %d is a tree.\n",t++);
else
printf("Case %d is not a tree.\n",t++);
}
}
#include<bits/stdc++.h>
using namespace std;;
const int Maxn = 1e5 + 1;
int fa[Maxn];
int find(int n)
{
if (fa[n]==0) return fa[n]=n;//巧妙的计算那些点用过,不要开数组贮存
if (fa[n]!=n) return fa[n]=find(fa[n]);
else return n;
}
int main() {
int x,y;
int T=0;
while (scanf("%d%d",&x,&y)!=EOF&&x>=0)
{
int flag = 1;
memset(fa,0,sizeof(fa));
if (x==0&&y==0)
{
printf("Case %d is a tree.\n",++T);
continue;
}
x=find(x);
y=find(y);
if(x!=y)//注意连通的边是有向的,只能是起点作父亲。一个点有父亲后再被链接就会成环。
{
fa[y]=x;
}
else //这俩根节点相同,成环
{
flag=0;
}
while (scanf("%d%d",&x,&y)!=EOF&&x)
{
if (find(y)!=y)//注意连通的边是有向的,只能是起点作父亲。一个点有父亲后再被链接就会成环。
{
flag=0;
}
else {
x=find(x);
y=find(y);
if (x!=y)
{
fa[y]=x;
}
else
{
flag=0;
}
}
}
int cnt=0;
for (int i =1;i<Maxn;i++)
{
if (fa[i]>0&&fa[i]==i) {
cnt++;
}
}
if (cnt>1)flag = 0;
if (flag)printf("Case %d is a tree.\n",++T);
else printf("Case %d is not a tree.\n", ++T);
}
}