原题地址:点击打开链接
该题用拓扑排序即可解决,建图之后先找入度为0的点,如果同时有2个或以上的顶点度数为0,则说明不可排序,如果拓扑排序结束后得到的答案小于顶点数则说明存在环,意思就是存在矛盾的关系式。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;
vector<int>next[26];
int p[26],pp[26],used[26],n;
char result[30],str[6];
int TpSort()
{
queue<int>que;
int res=0,u,v,i,size=0,book=0;
for(i=0;i<n;i++)
pp[i]=p[i];
for(i=0;i<n;i++)
{
if(pp[i]==0)
{
que.push(i);
}
}
while(!que.empty())
{
if(que.size()>1) //如果不止一个点的入度不为0则不可排序
book=1;
u=que.front();
que.pop();
result[size++]=u+'A';
for(i=0;i<next[u].size();i++) //将该点所有的边删除,更新与其相连顶点的入度
{
v=next[u][i];
pp[v]--;
if(pp[v]==0)
que.push(v);
}
}
result[size]='\0';
if(size<n)
return -1;
if(book==1)
return 0;
else
return 1;
}
int main()
{
int m,i,j,u,v,state,mark;
while(scanf("%d%d",&n,&m)&&(n||m))
{
state=0;
getchar();
for(i=0;i<n;i++)
{
p[i]=0;
next[i].clear();
}
for(i=0;i<m;i++)
{
gets(str);
if(state==1||state==-1) //如果已经可排序或者循环,则不用再继续判断,但仍然要继续输入
continue;
u=str[0]-'A';
v=str[2]-'A';
for(j=0;j<next[u].size();j++)
{
if(v==next[u][j])
break;
}
if(j==next[u].size())
{
next[u].push_back(v);
p[v]++; //记录定点的入度
memset(used,0,sizeof(used));
state=TpSort();
if(state==1||state==-1)
{
mark=i+1;
}
}
}
if(state==-1)
{
printf("Inconsistency found after %d relations.\n",mark);
}
else if(state==0)
{
printf("Sorted sequence cannot be determined.\n");
}
else
{
printf("Sorted sequence determined after %d relations: %s.\n",mark,result);
}
}
return 0;
}