sicily1034. Forest

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

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 <string>
#include <stdio.h>
#include <cstring>
#include <stack>
#include <vector>
#include <queue>
using namespace std;

int main()
{
    int n, m;
    while (scanf("%d%d", &n, &m) && n != 0)
    {
        int level[200];
        int w[200];
        memset(w, 0, sizeof(w));
        int deg[109];
        memset(deg, 0, sizeof(deg));
        int know[109];
        memset(know, 0, sizeof(know));
        vector<int> v[109];
        bool ch = true;
        int f, s;
        int dep= 0, wid = 0;
        for (int i = 0; i < m; ++ i)
        {
            scanf("%d%d", &f, &s);
            if (f == s)
            {
                ch = 0;
                continue;
            }
            ++ deg[s];
            if (deg[s] > 1)
            {
                ch = 0;
                continue;
            }
            v[f].push_back(s);
        }
        if (ch == 0)
        {
            cout << "INVALID" << endl;
            continue;
        }
        queue<int> q;
        for (int i = 1; i <= n; ++ i)
        {
            if (deg[i] == 0)
            {
                q.push(i);
                level[i] = 0;
                ++ w[0];
                if (w[0] > wid)
                {
                    wid = w[0];
                }
            }
        }
        if (q.empty())
        {
            cout << "INVALID" << endl;
            continue;
        }
        while (!q.empty() && ch != 0)
        {
            int tem = q.front();
            q.pop();
            stack<int> st;
            st.push(tem);
            while (!st.empty() && ch != 0)
            {
                int temp = st.top();
                st.pop();
                know[temp] = 1;
                for (int i = 0; i < v[temp].size(); ++ i)
                {
                    int ant = v[temp][i];
                    if (know[ant] == 0)
                    {
                        level[ant] = 1 + level[temp];
                        ++ w[level[ant]];
                        if (w[level[ant]] > wid)
                        {
                            wid = w[level[ant]];
                        }
                        if (level[ant] > dep)
                        {
                            dep = level[ant];
                        }
                        st.push(ant);
                    }
                    else
                    {
                        ch = 0;
                        break;
                    }
                }
            }
        }
        if (ch == 0)
        {
            cout << "INVALID" << endl;
        }
        else
        {
            cout << dep << " " << wid << endl;
        }
    }
}                                 



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值