POJ 1094

//拓扑排序的经典题目
//此题切忌:无法排序的情况下也可能出现环的情况
#include <iostream>
#include <string>
using namespace std;
#define arraysize 30
int map[arraysize][arraysize]; //存储邻接阵
int indegree[arraysize]; //存储节点入度
char resultset[arraysize]; //存储结果
int n,m;
int topsort()
{
    int i,j,k;
    memset(indegree,0,sizeof(indegree));
    memset(resultset,0,sizeof(resultset));
    for(i=1;i<n+1;++i)
    {
        for(j=1;j<n+1;++j)
        {
           if(map[i][j]==1)
               indegree[j]++;
        }
    }
    int num = 0;
 bool isOnly = false; //用于标记拓扑排序是否唯一
 for(i=1;i<n+1;++i)
    {
  int only = 0;  //判断拓扑排序是否唯一
        for(j=1;j<n+1;++j)
        {
            if(indegree[j]==0)
            {
                only++;
    if(only>1)   //在一次排序中出现了两个入度为0的节点,表明拓扑排序不唯一,不要立即返回,可能出现冲突情况,需要接着判断
     isOnly = true;                
            }
        }
  if(only==0)    //拓扑排序中环路的判断方式:一个入度为0的节点未找到,代表有环
   return 0;
  for(j=1;j<n+1;++j)
        {
            if(indegree[j]==0)
            {
                resultset[num] = 'A'+j-1;
                num++;
                indegree[j]--;
                for(k=1;k<n+1;++k)
                {
                    if(map[j][k]==1)
                       indegree[k]--;
                }
    break;
            }
        }
    }
    resultset[num]='\0'; //此出别忘了添加'\0'
 if(isOnly)    //拓扑排序不唯一
  return 1;
 else if(num==n && !isOnly) //可以进行排序
  return 2;
}
int main()
{
    freopen("1.txt","r",stdin);
    int i,j;
    char str[4];
    int result;
    bool isOver;
    while(cin>>n>>m)
    {
         if(n==0 && m==0)
            break;
         isOver = false;
         memset(map,0,sizeof(map));
         for(i=1;i<m+1;++i)
         {
             cin>>str;      
             map[str[0]-'A'+1][str[2]-'A'+1] =1; 
             result= topsort();  //边输入边进行拓扑排序
    if(result==0)   //产生了环
             {
                 isOver = true;
                 printf("Inconsistency found after %d relations.\n",i);
     for(j=i+1;j<m+1;++j)
      cin>>str;
     break;
             }
    else if(result==1)    //拓扑排序不唯一
     continue;   
             else if(result==2)    //可以进行排序
             {
                 isOver = true;
                 printf("Sorted sequence determined after %d relations: %s.\n",i,resultset);
     for(j=i+1;j<m+1;++j)
      cin>>str;
     break;
             }            
         }   
         if(!isOver)
         {
             printf("Sorted sequence cannot be determined.\n");      
         }  
    }
    return 0;
}

posted @ 2010-05-21 11:36  北海小龙  阅读(282)  评论(0编辑  收藏  举报