森林

//sicily 1034. Forest

// 1.如果有任一节点的入度>1 或者没有根节点,则不是森林,否则:
// 2.先找根节点(入度为0的节点),压入栈.
// 3.对栈中的根结点(当前)删除掉,把所有子节点压入栈,重复这过程.最后若所有结点都曾压入栈中,则能构成森林,反之则说明有环存在

#include
<iostream> //BFS求森林深度和宽度
#include<stdio.h>
#include
<vector>
#include
<stack>
#include
<cstring>
using namespace std;
struct Node
{
int inDgr; //入度数
vector<int >next; //表示它的孩子结点
int height;
};
int width[200]; //高度i上的宽度width[i]
int max_height,max_width;
int main()
{
int n,m,i;
while(scanf("%d%d",&n,&m)&&n)
{
Node node[
200];
for(i=1;i<=n;++i) //每次把所有结点的入度数初始化为0
node[i].inDgr=0;
bool isforest=true;
int f,c;
while(m--)
{
scanf(
"%d%d",&f,&c);
node[f].next.push_back(c);
node[c].inDgr
++;
if(node[c].inDgr>1) //说明有两条边指向同个结点
isforest=false;
}
if(!isforest)
{
printf(
"INVALID\n"); continue;
}
memset(width,
0,sizeof(width));
stack
<int> root_stack; //栈中元素是入度为0的节点
for(i=1;i<=n;i++)
if(node[i].inDgr==0)
{
root_stack.push(i);
//入度为0的节点压入栈
node[i].height=0;
width[
0]++; //一开始所有的根结点都在第0层
}

if(root_stack.empty()) //没有根结点,那么肯定是有环
{
printf(
"INVALID\n"); continue;
}
int roots=0;
max_height
=max_width=0;
while(!root_stack.empty())
{
roots
++;
int top=root_stack.top();
root_stack.pop();
if(max_height<node[top].height)
max_height
=node[top].height;

for(vector<int >::iterator ite=node[top].next.begin();ite!=node[top].next.end();++ite)
{
node[
*ite].height=node[top].height+1; //儿子节点的深度=父节点+1
width[node[*ite].height]++; //在这一高度上的宽度数增加1
root_stack.push(*ite);
}
}
if(roots<n) //环内任意结点的入度都至少为1,都不会被压入栈,所以小于n则说明存在环
{
printf(
"INVALID\n"); continue;
}
for (i=0;i<n;i++)
if(width[i]>max_width)
max_width
=width[i];
printf(
"%d %d\n",max_height,max_width);
}
return 0;
}

  

posted on 2011-08-24 16:32  sysu_mjc  阅读(228)  评论(0编辑  收藏  举报

导航