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.
题目解释:求解一个forest的depth和width。对于一个forest,可能包含多个tree,同时要求这个forest无环,没有出现两个边同时指向一个点的情况。使用深度搜索求解
解题思路:下面将提供2个写法,code1是能够通过所有测试样例的使用深度搜索算法解决的,
code2的解题思路是:先将所有的root找出来,然后制造一个节点ROOT,ROOT的子结点就是当前所有root。这就相当于将一个forest变成一个tree。然后对tree进行宽度搜索。但是code2不能通过全部测试样例,还没找到答案
CODE1
<pre name="code" class="cpp">#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
vector<int> forest[105];
int width[105];
bool visited[105], isloop;
int endPoints[105];
int W, D;
int vertex, edges;
void DFS(int start, int level){
if (visited[start]) {
isloop = false;
return;
}
visited[start] = true;
if (level > D) D = level;
width[level] ++;
if (width[level] > W) W = width[level];
for(int i = 0 ; i < forest[start].size(); i++){
if (!isloop) return;
int v = forest[start][i];
DFS(v, level+1);
}
}
int main(){
while (1) {
cin >> vertex >> edges;
if (vertex == 0) break;
W = 0;
D = 0;
memset(width, 0, sizeof(width));
memset(visited, false, sizeof(visited));
memset(endPoints, 0, sizeof(endPoints));
memset(forest, 0, sizeof(forest));
isloop = true;
if (edges >= vertex) isloop = false;
int a,b;
for (int i = 0; i < edges; i++) {
cin >> a >> b;
forest[a].push_back(b);
endPoints[b] ++;
}
for (int i = 1; i <= vertex; i++) {
if (endPoints[i] == 0) {
DFS(i, 0);
}
}
for(int i = 1; i <= vertex; i++){
if (!visited[i]) isloop = false;
}
if (!isloop) cout << "INVALID" << endl;
else cout << D << " " << W << endl;
}
return 0;
}
CODE2
#include <iostream>
#include <string.h>
#include <queue>
#define N 105
using namespace std;
int vertex, edges;
int depth, width;
int forest[N][N];
int endpoints[N];
int level[N];
int level_wid[N];
bool root[N];
bool visited[N];
void getMax(){
for (int i = 1; i <= vertex; i++) {
if (width < level_wid[i]) width = level_wid[i];
if (depth < level[i] -1) depth = level[i] -1;
}
}
bool getDepWid(int start){ // 遍历整棵树求深度和宽度
queue<int> q;
q.push(start);
level_wid[level[start]] ++;
while (!q.empty()) {
int frontnum = q.front();
int tmp = 0;
q.pop();
if (visited[frontnum] == true) return false; // 点已经被遍历过,说明出现了loop
else visited[frontnum] = true;
for(int i = 1; i <= vertex; i++){
if (forest[frontnum][i] == 1) {
level[i] = level[frontnum] +1;
level_wid[level[i]] ++;
q.push(i);
tmp ++;
}
}
}
return true;
}
int main(int argc, const char * argv[]) {
// insert code here...
while (1) {
cin >> vertex >> edges;
if (vertex == 0) break; // 说明输入结束
memset(forest, 0, sizeof(forest));
memset(root, false, sizeof(root));
memset(visited, false, sizeof(visited));
memset(endpoints, 0, sizeof(endpoints));
memset(level, 0, sizeof(level));
memset(level_wid, 0, sizeof(level_wid));
bool result = false;
int a,b;
for (int i = 0; i < edges; i++) {
cin >> a >> b;
forest[a][b] = 1;
endpoints[b]++;
}
depth = 0;
width = 0;
for(int i = 1; i <= vertex; i++){
if (endpoints[i] >= 2) { // 确保没有两条边指向同一个点
result = false;
break;
}
else if (endpoints[i] == 0) {
forest[vertex+1][i] = 1;
result = true;
}
}
if(result && !getDepWid(vertex+1)) result = false;
if (result) {
getMax();
cout << depth <<" " << width << endl;
}
else cout << "INVALID" << endl;
}
return 0;
}