/*1034.Forest(求传递闭包判断回路,判断是否为森林,存在入度超过1或有回路的不成森林)
*/
#include <iostream>
#include <stdlib.h>
#include <memory.h>
#include <vector>
using namespace std;
struct Node
{
vector<int> adj;
}node[101];
int n, m;
int inDegree[101];
int matrix[101][101];
int width[101];
int treeLevel;
int forestLevel;
inline void DFS(int k, int level)
{
//统计每一层的节点数
width[level]++;
//判断树的深度是否比森林深度大,若是更新森林深度
if(treeLevel < level)
treeLevel = level;
for(int i=0; i< node[k].adj.size(); i++)
{
DFS(node[k].adj[i], level+1);
}
}
inline bool isForest()
{
for(int i=1; i<=n; i++)
if(inDegree[i] > 1)
return false;
//求出图的传递闭包
// 例如 i->k,i可以到达k,则就在i列中,找出可以到达i的j,扫描k列所有行即可
for(int i=1; i<=n; i++)
for(int k=1; k<=n; k++)
if(matrix[i][k])
{
//扫描k列所有的行
for(int j=1; j<=n; j++)
if(matrix[j][i]) //如果存在j可达i,则说明j也可到k 则令其为1
matrix[j][k] =1;
}
//找完闭包后,要判断是否形成回路闭包,只需要判断是否存在节点i可以连通到自身
for(int i=1; i<=n ; i++)
if(matrix[i][i])
return false;
return true;
}
int main()
{
int start, end;
while(cin >> n >> m && n !=0)
{
memset(inDegree,0, sizeof(inDegree));
memset(matrix,0, sizeof(matrix));
memset(width,0, sizeof(width));
memset(node, 0, sizeof(node)); //注意要初始化node数组
for(int i=1; i<=m; i++)
{
cin >> start >> end;
matrix[start][end] = 1;
inDegree[end]++;
node[start].adj.push_back(end);
}
forestLevel =0;
if(!isForest()) //判断是否存在回路闭包或者是否存在入度超过1的点
cout << "INVALID" << endl;
else
{
for(int i=1; i<=n; i++)
{
//对森林每棵树进行DFS,统计出各颗树的深度和广度
if(inDegree[i] == 0)
{
treeLevel = 0;
DFS(i, 0);
if(treeLevel > forestLevel)
forestLevel = treeLevel;
}
}
int maxWidth = 0;
for(int i=0; i< 101; i++)
if(maxWidth < width[i])
maxWidth = width[i];
cout << forestLevel << " "<< maxWidth << endl;
}
}
system("pause");
return 0;
}
1034.Forest(判断是否为森林,存在入度超过1或有回路的不成森林)
最新推荐文章于 2018-06-13 13:30:16 发布