题目链接在此
解题思路:
1.设置inDegree数组,记录节点的入度,若再输入的过程中节点入度大于1,则立即判断forrest非法。
2.深搜DFS,用visit数组记录已访问的节点,判断是否存在环。
3.用widths数组记录每一层深度的节点数(即宽度)。
4.邻接矩阵adjacent记录节点之间的边。
<span style="font-size:18px;">#include<iostream>
#include<stdio.h>
#include<vector>
#include<string.h>
//#pragma warning(disable : 4996) //屏蔽VS对scanf的报错
using namespace std;
bool inDegree[105];
bool visit[105];
int widths[105];
vector<int> adjacent[105];
void dfs(int i, int currentDepth, bool& isValid, int& deepest, int& widest) {
if (visit[i]) {
isValid = false;
return;
}
visit[i] = true;
if (currentDepth > deepest)
deepest = currentDepth;
widths[currentDepth]++;
if (widths[currentDepth] > widest)
widest = widths[currentDepth];
for (int j = 0; j < adjacent[i].size(); j++)
dfs(adjacent[i][j], currentDepth + 1, isValid, deepest, widest);
}
int main() {
int nodeNum, edgeNum;
int edgeStart, edgeEnd;
scanf("%d %d", &nodeNum, &edgeNum);
while (nodeNum != 0) {
bool isValid = true;
int deepest = 0, widest = 0;
memset(inDegree, 0, sizeof(inDegree));
memset(visit, 0, sizeof(visit));
memset(widths, 0, sizeof(widths));
memset(adjacent, 0, sizeof(adjacent));
for (int i = 1; i <= edgeNum; i++) {
scanf("%d %d", &edgeStart, &edgeEnd);
if (inDegree[edgeEnd] || edgeStart == edgeEnd)
isValid = false;
else
inDegree[edgeEnd] = true;
adjacent[edgeStart].push_back(edgeEnd);
}
if (!isValid) {
printf("INVALID\n");
scanf("%d %d", &nodeNum, &edgeNum);
continue;
}
for (int i = 1; i <= nodeNum; i++)
if (!inDegree[i]) {
dfs(i, 0, isValid, deepest, widest);
}
for (int i = 1; i <= nodeNum; i++)
if (visit[i] == 0) {
isValid = false;
break;
}
if (isValid)
printf("%d %d\n", deepest, widest);
else
printf("INVALID\n");
scanf("%d %d", &nodeNum, &edgeNum);
}
return 0;
}</span>