题意就不说了,很明显的拓扑排序。借这道题总结一下拓扑排序吧。拓扑排序的思路很明确但我总觉得有很多的细节值得注意,写的时候总是缺点这少点那的,不断的调试总是浪费很多的时间,以下是我总结的几点:
(1)拓扑排序的结果一般分为三种情况:1、可以判断 2、有环出现了矛盾 3、条件不足,不能判断,思路上一定要分清楚三种情况的条件判断。
(2)初始化栈的时候,将入度为零的顶点入栈,然后弹出栈顶元素e,将e的邻接点的入度减一,若邻接点的入度也为零了,将该邻接点也入栈,如此循环,直到栈空。在这个过程中,栈中元素个数始终为一。若大于一则出现了多个顶点入度为零的情况,这时就无法辨别这几个顶点的先后顺序,这也就是条件不足的情况。若入度为零的顶点的个数为零,也就出现了环的情况,但这一情况必须是在弹出的元素的个数小于顶点总个数,所以在结束的时候需要将计数器与总个数相比较,因为会出现这样的情况:A<B,B<C,C<A,D<E,一开始时将D进栈,然后D出E进,E出时没有元素可进了,若不在最后再进行一次比较的话,那么就认为可以判断了,然而其实是有环的。
再说说这道题吧,这道题不仅需要判断这三种情况,而且还要判断在处理第几个关系时出现前两种情况,对于本道题来说三种情况是有优先级的。前两种情况是平等的谁先出现先输出谁的相应结果,对于第三种情况是在前两种情况下都没有的前提下输出相应结果的。
代码如下:
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
int indegree[27],edge[27][27],sequence[27],start[27],end[27],length;
char vertex[27];
int find(char c)
{
int i;
for(i=0;i<length;i++)
if(vertex[i]==c) return i;
vertex[length]=c;
return length++;
}
int f(int n)
{
int i,e,count=0,len=0;
bool flag1,flag2;
queue <int> Q;
int aa[27];
flag1=flag2=false;
for(i=0;i<n;i++) aa[i]=indegree[i];
memset(sequence,0,sizeof(sequence));
for(i=0;i<length;i++)
if(aa[i]==0) Q.push(i);
do
{
if(Q.size()>1) flag2=true;
else if(Q.size()==0) flag1=true;
count++;
e=Q.front(),Q.pop();
sequence[len++]=e;
for(i=0;i<n;i++)
if(edge[e][i])
{
if(--aa[i]==0) Q.push(i);
}
}while(!Q.empty());
if(flag1 || count<length ) return 1;
else if(flag2) return 2;
return 0;
}
int main()
{
int i,j,k1,k2,m,n,ss,tt,l;
char s,t,c;
bool flag1,flag2;
while(cin>>n>>m,m&&n)
{
memset(indegree,0,sizeof(indegree));
memset(edge,0,sizeof(edge));
flag1=flag2=false;
for(length=i=0;i<m;i++)
{
getchar();
cin>>s>>c>>t;
ss=find(s); tt=find(t);
if(ss!=tt && !edge[ss][tt]) indegree[tt]++;
edge[ss][tt]=1;
l=f(n);
if(!flag1 && l==1)
{
flag1=true;
k1=i+1;
break;
}
else if(length>=n && !flag2 && l==0)
{
flag2=true;
k2=i+1;
break;
}
}
if(flag1)
{
cout<<"Inconsistency found after "<<k1<<" relations."<<endl;
}
else if(flag2)
{
cout<<"Sorted sequence determined after "<<k2<<" relations: ";
for(j=0;j<n;j++)
cout<<vertex[sequence[j]];
cout<<"."<<endl;
}
else
{
cout<<"Sorted sequence cannot be determined."<<endl;
}
for(i++;i<m;i++){getchar();cin>>s>>c>>t;}
}
return 0;
}