题目链接:点击打开链接
题意是给出具有n个节点和m条边的森林,根节点深度为0,求最大深度和最大宽度(同一层的节点数),如果有环,则输出“INVALID"。可用深度优先搜索解答。
// source code of submission 840674, Zhongshan University Online Judge System
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int width[105];
int in[105]; //入度
bool visit[105];
int depth;
int ok;
int totalNodes;
struct Node
{
Node()
{
k = 0;
}
int k;
int child[105];
}node[105];
//dfs
void traverse(int root, int level)
{
width[level]++; //第level层的节点数++
visit[root] = true;
totalNodes++;
if(level > depth)//最大深度
depth = level;
for(int i = 0; i < node[root].k; ++i)
{
if(visit[node[root].child[i]])
{
ok = 0;
return;
}
traverse(node[root].child[i], level+1);
}
}
int main()
{
int n, m;
int i, j;
int a, b;
while(scanf("%d%d", &n, &m) != EOF && n)
{
for(i = 1; i <= n; ++i)
{
node[i].k = 0;
}
memset(in, 0, sizeof(in));
memset(width, 0, sizeof(width));
memset(visit, false, sizeof(visit));
for(i = 1; i <= m; ++i)
{
scanf("%d%d", &a, &b);
node[a].child[node[a].k++] = b;
in[b]++;
}
ok = 0;
depth = -1;
totalNodes = 0; //总节点数为0
for(i = 1; i <= n; ++i)
{
if(in[i] == 0)//入度为0是根节点
{
ok = 1;
traverse(i, 0);
if(ok == 0)
break;
}
}
if(!ok || totalNodes < n) //ok为0或总节点数小于n说明有环
{
printf("INVALID\n");
}
else
{
j = 0;
for(i = 0; i <= depth; ++i)//求最大宽度
{
if(j < width[i])
j = width[i];
}
printf("%d %d\n", depth, j);
}
}
return 0;
}