An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.
Input
Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.
Output
For each problem instance, output consists of one line. This line should be one of the following three:
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
这道题目考察了拓扑排序的基本思想:每一步寻找一个入度为0的结点,然后删除之。将这个结点指向的结点入度减1。删除从这个结点出发的所有边
同时考察了对于一个有向图是否有环、是否严格有序的判断。(当发现多个结点的度为0时,则不是严格有序。当发现没有结点入度为0时,则有环)
需要注意的是逻辑上的关系。“Sorted sequence cannot be determined.”这个判断,要放在最后,即只有发现了所有的点都没有环,且并没有发现严格有序性质的时候,才可以判为“Sorted sequence cannot be determined."
逻辑上的判决一定要注意优先级。
这个问题中优先级最高的是判断有环。一旦发现找不到度为0的结点,则立即return。
第二优先级是是否严格有序的判断。当每一步能且只能找到一个度为0的结点,则return。
第三优先级是无法确定。(当发现无法确定时,并不能立即return,因为还需要判断是否有环)
思维方式:问问自己,当条件x成立时,另外的条件y,z是否一定不成立。如果一定不成立,则可以断言return。否则必须继续判断下去。
注意:输入一组数据,判断一组数据,若有环或已严格排序则可直接输出结果,后续读入的不做处理,不影响前面的输出结果。但是若前面两个均不成立,切记不严格排序是最后得出的。
附上代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include<algorithm>
using namespace std;
int indegree[27]; //入度
int map[27][27]; //图
int queue[27]; // 每次找到入度为0的点后,存储要输出的顺序
int TopoSort(int n) //拓扑排序
{
int count=0; //记录解空间中零入度顶点的个数
int temp[27]; //对入度顶点备份
int pos; //记录一个零入度顶点的数目
int i,j;
int m; //零入度顶点的个数
int flag=1; //flag=1:有序 flag=-1:不能确定
for (i=1; i<=n; i++)
{
temp[i] = indegree[i]; //备份
}
for (i=1; i<=n; i++) //遍历n遍,必须把图全部遍历完(根据当前输入的,尽管map全部初始化为0了,只要根据当前输入的所有条件判断)
{
m = 0;
for (j=1; j<=n; j++) //查找零入度顶点的个数
{
if (temp[j] == 0)
{
m ++;
pos = j; //记录一个零入度顶点的位置
}
}
if (m == 0) //零入度顶点的个数==0:有环
{
return 0;
}
if (m > 1) //零入度顶点的个数>1,说明还有其他两点之间没确定关系,判断是无序(只有1到n个点确定关系,且没有环,根据拓扑排序才能确定有序)
{
flag=-1; //当知道无序时,并不一定知道该图是否有环,因此要继续遍历,可别急着退出...
}
queue[count++] = pos; //零入度顶点入队
temp[pos] = -1; //将零入度顶点的入度置为-1
for (j=1; j<=n; j++) //删除以pos为起点的边
{
if (map[pos][j] == 1)
{
temp[j] --; //相应定点的入度减1
}
}
}
return flag;
}
int main()
{
int n,m;
int sign; //当sign=1时,程序已经得出结果,不需再考虑后面的输入
string str;
while (scanf("%d%d",&n,&m) && n!=0 && m!=0)
{
memset(map,0,sizeof(map));
memset(indegree,0,sizeof(indegree));
sign=0;
for (int i=1; i<=m; i++)
{
cin>>str;
if (sign)
{
continue; //一旦得出结果,对后续的输入置之不理!
}
int u = str[0]-'A'+1;
int v = str[2]-'A'+1;
map[u][v] = 1;
indegree[v] ++;
int s = TopoSort(n);
if (s == 0) //有环
{
printf("Inconsistency found after %d relations.\n",i);
sign=1;
}
if (s == 1) //有序
{
printf("Sorted sequence determined after %d relations: ",i);
for (int j=0; j<n; j++)
{
printf("%c",queue[j]+'A'-1); //根据进队顺序输出字符,整型转字符型
}
printf(".\n");//每句话的结尾的点号,记得输出!
sign=1;
}
}
if(!sign) //无法得出结果
{
printf("Sorted sequence cannot be determined.\n");
}
}
return 0;
}