Description
Input
Output
Sorted sequence determined after xxx relations: yyy...y.
Sorted sequence cannot be determined.
Inconsistency found after xxx relations.
where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence.
Sample Input
4 6
A<B
A<C
B<C
C<D
B<D
A<B
3 2
A<B
B<A
26 1
A<Z
0 0
Sample Output
Sorted sequence determined after 4 relations: ABCD.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined.
题意:
这道题有隐含这一信息,每输入一对关系,如果判定有结果,则可以忽略后面输入数据,即使后面输入数据能改变结果,也不用管。所以应该每输入一个关系就去更新当前的图,然后进行一趟拓扑排序。一旦产生结果,再对后面的数据处理下,就可以输出结果。
一、当输入的字母全部都在前n个大写字母范围内时:
(1) 最终的图 可以排序:
在输入结束前如果能得到最终的图(就是用这n个字母作为顶点,一个都不能少);而且最终得到的图 无环;只有唯一一个 无前驱(即入度为0)的结点,但允许其子图有多个无前驱的结点。
在这步输出排序后,不再对后续输入进行操作
(2)输出矛盾
在输入结束前如果最终图的子图有环
在这步输出矛盾后,不再对后续输入进行操作
(3)输出无法确认排序
这种情况必须全部关系输入后才能确定,其中又有2种可能
①最终图的字母一个不缺,但是有多个 无前驱结点
②输入结束了,但最终的图仍然字母不全,与 无前驱结点 的多少无关
二、当输入的字母含有 非前n个大写字母 的字母时(超出界限):
(1) 输出矛盾
输入过程中检查输入的字母(结点),若 前n个大写字母 全部出现,则在最后一个大写字母出现的那一步 输出矛盾
(2) 输出无法确认排序
最后一步输入后,前n个大写字母 仍然未全部出现,则输出 无法确认排序
PS:在使用“无前驱结点”算法时必须要注意,在“矛盾优先”的规律下,必须考虑一种特殊情况,就是多个无前驱结点与环共存时的情况,即输入过程中子图都是有 多个无前驱结点,最后一步输入后出现了环,根据算法的特征,很容易输出“不能确认排序”,这是错的,必须适当修改算法,输出“矛盾”。
#include<stdio.h> #include<string.h> int map[27][27],indegree[27],q[27]; int TopoSort(int n) //拓扑排序 { int c=0,temp[27],loc,m,flag=1,i,j; ////flag=1:有序 flag=-1:不确定 for(i=1;i<=n;i++) temp[i]=indegree[i]; for(i=1;i<=n;i++) { m=0; for(j=1;j<=n;j++) if(temp[j]==0) { m++; loc=j; } //查找入度为零的顶点个数 if(m==0) return 0; //有环 if(m>1) flag=-1; // 无序 q[c++]=loc; //入度为零的点入队 temp[loc]=-1; for(j=1;j<=n;j++) if(map[loc][j]==1) temp[j]--; } return flag; } int main() { int m,n,i,sign; //当sign=1时,已得出结果 char str[5]; while(scanf("%d%d",&n,&m)) { if(m==0&&n==0) break; memset(map,0,sizeof(map)); memset(indegree,0,sizeof(indegree)); sign=0; for(i=1;i<=m;i++) { scanf("%s",str); if(sign) continue; //一旦得出结果,对后续的输入不做处理 int x=str[0]-'A'+1; int y=str[2]-'A'+1; map[x][y]=1; indegree[y]++; int s=TopoSort(n); if(s==0) //有环 { printf("Inconsistency found after %d relations. ",i); sign=1; } if(s==1) //有序 { printf("Sorted sequence determined after %d relations: ",i); for(int j=0;j<n;j++) printf("%c",q[j]+'A'-1); printf(". "); sign=1; } } if(!sign) //不确定 printf("Sorted sequence cannot be determined. "); } return 0;