题目地址http://acm.pku.edu.cn/JudgeOnline/problem?id=1094

 

  每次读入一条边后,对新图作DFS找是否有环,如果有环则不用进行拓扑排序了,这种属于不能确定的情况。

否则进行拓扑排序, 因为拓扑排序的序列可能是不唯一的,拓扑排序不唯一的情况比较好判断,就是如果每次队列

中如果有多于一个点(这个点代表入度为0的点),则不唯一,如果不出现这样的点,则有唯一拓扑排序序列,最后

输出即可。

 

代码
#include <iostream>
#include 
<cstdio>
#include 
<cstring>
#include 
<queue>
using namespace std;
const int MAXN = 30;
const int WHITE = 0;
const int BLACK = 1;
const int GRAY = 2;
int ind[MAXN];
bool map[MAXN][MAXN];
int  visited[MAXN];
bool now[MAXN];
int n,m;
bool hasCircle;
bool notDet;
bool found;
char res[MAXN];

int step;

void dfs(int v)
{
    visited[v] 
= GRAY;
    
for (int i=0;i<n;i++)
    {
        
if(i==v)
        {
            
continue;
        }
        
if (now[i]&&visited[i]==WHITE)
        {
            
if (map[v][i])
            {
                dfs(i);
                
if (hasCircle)
                {
                    
return;
                }
            }
        }
        
else if(now[i]&&map[v][i]&&visited[i]==GRAY)
        {
            hasCircle 
= true;
            
return;
        }

    }
    visited[v] 
= BLACK;

}

void topsort()
{
    queue 
<int> q;
    
for (int i=0;i<n;i++)
    {
        
if (now[i]&&ind[i]==0)
        {
            q.push(i);
        }
    }
    
int cnt = 0;
    
bool tMap[MAXN][MAXN];
    
int tind[MAXN];
    memcpy(tind,ind,
sizeof(ind));
    memcpy(tMap,map,
sizeof(map));
    
while (!q.empty())
    {
        
if (q.size()>1)
        {
            notDet 
= true;
        }
        
int cur = q.front();
        q.pop();
        res[cnt
++= cur+'A';
        
for (int i=0;i<n;i++)
        {
            
if (now[i]&&tMap[cur][i])
            {
                tMap[cur][i] 
= false;
                tind[i]
--;
                
if (tind[i]==0)
                {
                    q.push(i);
                }
            }
        }
    }
    
if (cnt==n&&!notDet)
    {
        found 
= true;
        res[cnt]
='\0';
    }
}
int main()
{
    
while (scanf("%d%d",&n,&m)!=EOF&&!(n==0&&m==0))
    {
        memset(map,
false,sizeof(map));
        memset(ind,
0,sizeof(ind));
        memset(now,
false,sizeof(now));
        
char inst[10];
        
char a,b;
         hasCircle 
= false;
         found 
= false;
        
for (int i=0;i<m;i++)
        {
            scanf(
"%s",inst);
            a 
= inst[0];b=inst[2];
            
if(hasCircle||found)
            {
                
continue;
            }
            map[a
-'A'][b-'A'= true;
            now[a
-'A'= true;
            now[b
-'A'= true;
            ind[b
-'A']++;
            memset(visited,
0,sizeof(visited));
            
if (!found)
            {
                
for (int j=0;j<n;j++)
                {
                    
if (now[j]&&!visited[j])
                    {
                        dfs(j);
                        
if (hasCircle)
                        {
                            step 
= i+1;
                            
break;
                        }
                    }
                }
                
if (!hasCircle)
                {
                    notDet 
= false;
                    topsort();
                    
if(found)
                    {
                        step 
= i+1;
                    }
                }
            }
        }
        
if(hasCircle)
        {
            printf(
"Inconsistency found after %d relations.\n",step);
        }
        
else if(found)
        {
            printf(
"Sorted sequence determined after %d relations: %s.\n",step,res);
        }
        
else
        {
            printf(
"Sorted sequence cannot be determined.\n");

        }
    }
    
return 0;
}