Sorting It All Out
Time Limit: 1000 ms Memory Limit: 10000 KiB
Problem Description
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.
http://acm.sdut.edu.cn/onlinejudge2/index.php/Home/Contest/contestproblem/cid/2876/pid/1832
给定一组字母的大小关系,要你判断是否在某一次读入后,能够判断
1.该字母序列有序,并依次输出;
2.该序列不能判断是否有序;
3.该序列字母次序之间有矛盾,即有环存在。
而这三种形式的判断应该遵循这样的顺序:先判断是否有环(3),再判断是否有序(1),最后才能判断是否能得出结果(2)。
注意:对于(2)必须遍历完整个图!!,而(1)和(3)一旦得出结果,对后面的输入就不用做处理了。
#include<stdio.h>
#include<string.h>
int map[30][30],indegree[30],temp[30],stack[30];
char s[5];
int n;
int tuopu()
{
int i,j,num,tail = -1,now,flag = 1;
for(i =0; i < n; i ++)//将每个点的入度先用临时数组存起来,因为一会要修改
{
temp[i] = indegree[i];
}
for(i = 0; i < n; i ++)//把每个入度为0的点删除,遍历n个点(如果能得出结果的话)
{
num = 0;//入度为0的点的个数
for(j = 0; j < n; j ++)
{
if(temp[j] == 0)
{
now = j;//标记这个入度为0的点
num ++;
}
}
if(num == 0)//没有入度为0的点,证明存在环,关系矛盾,直接返回,得出结果
return -1;
if(num > 1)//入度为0的点的个数大于1,也得不出关系,但现在不能直接返回,因为当前也有可能存在环,只是还没判断到,要等大循环结束
flag = 0;
stack[++tail] = now;//当前只有一个入度为0的点,有可能能得出结果,先把当前的信息存起来
temp[now] = -1;//此入度为0的点标记为-1,避免再次判断
for(j = 0; j < n; j ++)//把此点连接的点入度减1
{
if(map[now][j]==1)
temp[j] --;
}
}
return flag;
}
int main()
{
int i,j,m,a,b,flag,sign;
while(scanf("%d %d",&n, &m) != EOF)//前n个大写字母,m个关系
{
if(n == 0&&m == 0)
return 0;
sign = 0;//标记,为1表示如果当前已经确定了结果,并且输出了结果,那就等着输入结束
memset(map,0,sizeof(map));
memset(indegree,0,sizeof(indegree));
for(i = 0; i < m; i ++)
{
scanf("%s",s);
if(sign)//已经输出了结果,不处理数据,continue,
continue;
a = s[0] -'A';
b = s[2] - 'A';
map[a][b] = 1;//邻接矩阵存边
indegree[b] ++;//b的入度加一
flag =tuopu();//m每给出一条信息,就重新判断,判断当前的已知信息能不能得出结果
if(flag == -1)//关系矛盾
{
printf("Inconsistency found after %d relations.\n",i+1);
sign = 1;//已经得出了结果
}
else if(flag)//得出关系
{
printf("Sorted sequence determined after %d relations: ",i+1);
for(j = 0; j < n; j++)
{
printf("%c",stack[j]+'A');
}
printf(".\n");
sign = 1;
}
}
if(!sign)//当前所给信息不足以得出关系
{
printf("Sorted sequence cannot be determined.\n");
}
}
return 0;
}