标题:森林搜索问题C实现
只看楼主
yfhanbing
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2008-10-25
 问题点数:0 回复次数:0 
森林搜索问题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 
搜索更多相关主题的帖子: 森林 搜索 
2008-10-25 21:44



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-240587-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.279559 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved