sicily 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 0
1 1
1 1
3 1
1 3
2 2
1 2
2 1
0 88

Sample Output

0 1
INVALID
1 2
INVALID

分析:

本题要求森林的深度和宽度,建议用深搜,因为广搜的循环控制条件很难写,极易出错或者死循环。要注意图生成的森林中,可能会出现公共子节点以及环等不合法情况,要注意判断条件。DFS过程中遇到了已经访问过的节点说明有公共子节点的存在,DFS完成后仍有节点未被访问说明有环存在。另外,一次完整的DFS过程中求得的广度只是一棵树的广度,要对同一深度的节点全部统计才能得到森林的广度。

代码:

// Problem#: 1034
// Submission#: 1795986
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <iostream>
#include <cstring>
using namespace std;

#define N 101
#define M 101

bool flag;
bool buffer[N][N];
bool visit[N];
bool isroot[N];
int maxd,n,m,maxb;
int b[N];

void dfs( int p, int td ){
    if( visit[p] ){
        flag = false;
        return ;
    }
    visit[p] = true;
    maxd = td>maxd ? td : maxd;
    if(++b[td]>maxb) maxb = b[td];
    for( int i=1 ; i<=n ; i++ ){
        if( buffer[p][i] ){
            if(!flag) return ;
            dfs(i,td+1);
        }else
            continue;
    }
}

int main(){
    int x,y;
    while( cin>>n>>m && n ){
        memset(buffer,0,sizeof(buffer));
        memset(visit,0,sizeof(visit));
        memset(isroot,true,sizeof(isroot));
        flag = true;
        if(m>=n) flag = false;
        for( int i=0 ; i<m ; i++ ){
            cin >> x >> y;
            buffer[x][y] = true;
            isroot[y] = false;
        }
        maxd = maxb = 0;
        memset(b,0,sizeof(b));
        for( int i=1 ; i<=n ; i++ )
            if( isroot[i] ) dfs(i,0);
        for( int i=1 ; i<=n ; i++ ){
            if( !visit[i] ){
                flag = false;
                break;
            }
        }
        if( flag ) cout << maxd << " " << maxb;
        else cout << "INVALID";
        cout << endl;
    }
    return 0;
}

转载于:https://my.oschina.net/u/235391/blog/96618

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值