sicily-1034. Forest

1034. Forest


限制条件
时间限制: 1 秒, 内存限制: 32 兆


题目描述

     In the field of computer science, forest is important and deeply researched , it is a model for many data structures . Now it’s your job here to calculate the depth and width of given forests.
     Precisely, a forest here is a directed graph with neither loop nor two edges pointing to the same node. Nodes with no edge pointing to are roots, we define that roots are at level 0 . If there’s an edge points from node A to node B , then node B is called a child of node A , and we define that B is at level (k+1) if and only if A is at level k .
      We define the depth of a forest is the maximum level number of all the nodes , the width of a forest is the maximum number of nodes at the same level.

输入格式
There’re several test cases. For each case, in the first line there are two integer numbers n and m (1≤n≤100, 0≤m≤100, m≤n*n) indicating the number of nodes and edges respectively , then m lines followed , for each line of these m lines there are two integer numbers a and b (1≤a,b≤n)indicating there’s an edge pointing from a to b. Nodes are represented by numbers between 1 and n .n=0 indicates end of input.


输出格式

For each case output one line of answer , if it’s not a forest , i.e. there’s at least one loop or two edges pointing to the same node, output “INVALID”(without quotation mark), otherwise output the depth and width of the forest, separated by a white space.

样例输入
1 0
1 1
1 1
3 1
1 3
2 2
1 2
2 1
0 88


样例输出
0 1
INVALID
1 2
INVALID


题目来源
ZSUACM Team Member

这道题的意思是求一个森林的深度和宽度。题目输入有多组测试样例以n=0结束,每组测试样例第一行为n,m (0<=n,m<=100,m<=n*n),接下来有m行,每行输入为a,b,表示边缘a指向b。

如果是森林输出森林的深度和宽度,反之输出INVALID。

这道提的思路主要深度优先搜索,只要排除入度大于一,和成环的情况就可以了。

下面是代码:

//1034. Forest 
//2016.12.07

#include <iostream>
#include <cstring>
#include <cstdlib>

using namespace std;

bool map[105][105];  //标记是否有边
int in[105];   //入度
bool vis[105];  //是否遍历
int level[105];   //宽度
bool flag;
int n,m,w,d;

void dfs(int r,int dp)
{
	d = max(d,dp);
	
	for(int i=0;i<=n;i++)
	{
		if(map[r][i])
		{
			level[dp+1]++;
			
			vis[i]=true;
			dfs(i,dp+1);
		}
	}
}

int main()
{
	while(cin>>n && n!=0)
	{
		memset(map,false,sizeof(map));
		memset(in,0,sizeof(in));
		memset(vis,false,sizeof(vis));
		memset(level,0,sizeof(level));
		
		cin>>m;
		int a,b,i;
		
		flag=false;
		for(i=1;i<=m;i++)
		{
			cin>>a>>b;
			map[a][b]=true;
			in[b]++;
			if(in[b]>1)
				flag=true;
		}
		
		if(flag)  //排除入度大于一的情况
		{
			
			cout<<"INVALID"<<endl;
			continue;
		}
			
			
		d=0;
		for(i=1;i<=n;i++)
		{
			if(in[i]==0)
			{
				level[0]++;
				vis[i]=true;
				dfs(i,0);
			}
		}
		
		for(i=1;i<=n;i++)
		{
			if(!vis[i])
				break;
		}
		
		if(i<=n)   // 排除成环的情况
		{
			cout<<"INVALID"<<endl;
			continue;
		}
			
		
		w=0;
		for(i=0;i<=n;i++)
			w=max(w,level[i]);
		cout<<d<<" "<<w<<endl;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值