SOJ 1034. Forest

Description

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.

Input

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.

Output

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.

Sample Input

1 01 11 13 11 32 21 22 10 88

Sample Output

0 1INVALID1 2INVALID

Problem Source

ZSUACM Team Member


#include<iostream>
#include<stdio.h>
#include<memory.h>
#include<vector>
#include<algorithm>

using namespace std;

  vector<int> a[105];    //存储每个点的邻接表
  bool isforest;         // 是否是森林的判断
  bool visit[105];       //是否访问过这一节点
  int width[105];        //每一层的宽度
  int depth,wid;         //森林的深度和宽度
  int in[105];           // 保存每个节点的入度,根据定义,入度不能>=2
void dfs(int currvet,int level)
{
  if(visit[currvet])
  {
  	isforest=false;
  	return ;
  }
   visit[currvet]=true;
   width[level]++;       //遍历到了下一层,并且是合法的点,则该层的宽度+1 
   if(wid<width[level])
   	wid=width[level];
   if(depth<level)
   	depth=level;            
   for (int i = 0; i < a[currvet].size(); ++i)
   {
   	/* code */
   	  dfs(a[currvet][i],level+1);
   }
  
}  
int main()
{
	int vertex,edge;
	while(cin>>vertex>>edge,vertex)
	{
		//初始化操作在下面,在这个循环的i初始值为0
       for (int i = 0; i <= vertex; ++i)
       {
       	/* code */
          visit[i]=false;
          width[i]=0;
          a[i].clear();
          in[i]=0;
       }
       wid=depth=0;
       isforest=true;
       for (int i = 0; i < edge; ++i)
       {
       	/* code */
       	int first,second;
       	cin>>first>>second;
       	a[first].push_back(second);
       	in[second]++;
       	if(in[second]>=2)
       		isforest=false;
       }
       if(isforest)
       {
         for (int i = 1; i <= vertex; ++i)
         {
       	/* code */
         	if(!in[i])   
              dfs(i,0);  //如果入度为0,则说明这个是根节点,从第0层开始深搜。
         }
       }  
       //针对1 3  这种情况,不是森林,2节点没有被访问到,则为非法的。
       for (int i = 1; i <= vertex; ++i)
       {
       	/* code */
          if(!visit[i])
          	isforest=false;
       }
      if(!isforest)
      {
    	cout<<"INVALID"<<endl;
        continue;
      }
     else 
  	    cout<<depth<<" "<<wid<<endl;
	  }

	//system("pause");
	return 0;
}  



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值