来源:http://soj.sysu.edu.cn/show_problem.php?pid=1004&cid=2387
hit
1.先找到每棵树的根再BFS,不然就有可能出现把一棵好树判断为非法树的情况。
2.树不合法有两种情况:(1)有环,(2)交叉;
3.树不合法的判断方法:(1)BFS时访问已访问之节点:交叉和环不含根节点的情况 (2)BFS结束后,仍有NODE未访问:环包含根节点的情况
代码
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
int vectorNum, edgeNum;
bool isVisited[101];
bool adjMatrix[101][101];
int depth[101];
int levelWidth[101];
bool valid;
void bfs(int start);
bool isRoot(int node);
bool allVisited();
int main() {
while (cin >> vectorNum >> edgeNum && vectorNum != 0) {
// initialize
valid = true;
memset(isVisited, false, 101*sizeof(bool));
memset(adjMatrix, false, 101*101*sizeof(bool));
memset(depth, 0, 101*sizeof(int));
memset(levelWidth, 0, 101*sizeof(int));
// read edges
int a, b;
for (int i = 0; i < edgeNum; i++) {
cin >> a >> b;
adjMatrix[a][b] = true;
}
//bfs
for(int i = 1; (i <= vectorNum) && valid; i++) {
if (false == isVisited[i] && isRoot(i)) bfs(i);
}
// output
if ((!valid) || (!allVisited())) {
cout << "INVALID" << endl;
} else {
int forestWidth = -1;
int level = 0;
for (;levelWidth[level] != 0;level++) {
if (levelWidth[level] > forestWidth) forestWidth = levelWidth[level];
}
cout << level - 1 << ' ' << forestWidth << endl;
}
}
return 0;
}
void bfs(int start) {
queue<int> q;
q.push(start);
depth[start] = 0;
levelWidth[depth[start]]++;
int node;
while (!q.empty()) {
node = q.front();
isVisited[node] = true;
q.pop();
for (int i = 1; i <= vectorNum; i++) {
if (adjMatrix[node][i]) {
// the loop || to edge point to the same vector
if (!isVisited[i]) {
q.push(i);
depth[i] = depth[node] + 1;
levelWidth[depth[i]]++;
} else {
valid = false;
return;
}
}
}
}
return;
}
bool isRoot(int node) {
for (int i = 1; i <= vectorNum; i++) {
if (adjMatrix[i][node]) return false;
}
return true;
}
// if valid , every node should have been visited
bool allVisited() {
for (int i = 1; i <= vectorNum; i++) {
if (!isVisited[i]) return false;
}
return true;
}