森林搜索问题C实现
程序代码:
/****************************************** 森林搜索问题 (输入:forest.in 标准输出) 问题描述: 在计算机科学的领域中,森林是一个很重要的概念,并且人们对它进行了深入的研究。它是许多数据结构的模型。 现在你的工作是计算给定森林的深度和宽度。 精确地说,这里的森林是一个有方向的有向图,该图没有环,并且不存在两条边指向相同的节点。没有边指向的节点称为根,我们定义根的层数为0。如果有一条边从A指向B,称B节点为A的孩子节点,同时,如果A的层数为K,则B的层数为(K+1)。 输入: 有一些测试用例。对于每个测试用例,在第一条行中有两个数字n和m(1≤n≤100, 1≤m≤100,m≤n*n),分别表示节点和边的数目。接下来的m行,每一行有两个整数a和b(1≤a,b≤n)表示有一条边从a指向b。节点用1至n之间的数字表示。输入以n=0结束。 输出: 每一个测试用例用一行输出结果,如果它不是一个森林,例如:至少有一个环或两条边指向相同的结果,则输出“INVALID”(没有标志),否则输出该森林的深度和宽度,用一个空格隔开。 样例输入: 1 0 1 1 1 1 3 1 1 3 2 2 1 2 2 1 0 88 样例输出: 0 1 INVALID 1 2 INVALID **********************************************8/ //www. namespace std ; int *Visit ; int **Map ; //记录森林 int *Degree ; int N, M ; //节点数与边数 int *Width ; //记录每一层的宽度 int MaxWidth ; int MaxLevel ; int NowLevel ; bool Cricle ; queue<int> Q ; //存放根节点 bool degreeOK() { if(N < M || N == M ) return false ; for(int i=0; i<N; i++) { for(int j=0; j<N; j++) Degree[i] += Map[j][i] ; if(Degree[i] >1 ) //两个节点同时指向一条边,返回 return false ; if(Degree[i] == 0 ) { Width[0]++ ; Q.push(i) ; } } if(Q.empty() ) //没有根节点,返回 return false ; return true ; } void DFS (int v, int level) { if(Cricle) return ; NowLevel = (NowLevel>level ? NowLevel : level ); for (int i=0; i<N; i++) { if (Map[v][i]) { if (Visit[i]) Cricle=true; else { Width[level]++ ; //统计当前层次的节点数。 Visit[i]=true; DFS(i, level+1); } } } } bool haveCricle() { int v ; int node = Width[0] ; while(!Q.empty() ) { v = Q.front() ; Q.pop() ; NowLevel = 1 ; Cricle = false ; Visit[v] = true ; DFS(v, 1 ) ; //从根节点开始遍历 if(Cricle ) { return true ; } MaxLevel = ( MaxLevel>NowLevel ? MaxLevel : NowLevel ); } MaxWidth = Width[0] ; int i=0 ; while(Width[++i] != 0 && i<=M ) //统计访问节点,及最大宽度 { MaxWidth = MaxWidth > Width[i] ? MaxWidth : Width[i] ; node +=Width[i] ; } if(node!=N) //还有节点没访问,表示有环。 { return true ; } return false ; } void play() { MaxWidth = 0 ; MaxLevel = 0 ; while(!Q.empty() ) Q.pop() ; if( degreeOK() ) //判断是否有两个节点同时指向一条边, { if (haveCricle()) //判断是否有环 { cout<<"INVALID"<<endl; } else cout<<MaxLevel-1<<" "<<MaxWidth<<endl; } else cout<<"INVALID"<<endl; } void main() { ifstream fin("forest.in", ios::in) ; int a, b ; fin>>N ; while( N!=0 ) { fin>>M ; Map = new int*[N] ; Visit = new int[N] ; Degree = new int[N] ; Width = new int[M+1] ; for(int i=0; i<N; i++) { Map[i] = new int[N] ; Visit[i] = false ; Degree[i] = 0 ; for(int j=0; j<N; j++) Map[i][j] = 0 ; } for( i=0; i<M; i++) { fin>>a>>b ; Map[a-1][b-1] = 1 ; Width[i] = 0 ; } Width