Sorting It All Out
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 //0 0 时结束 Sample Output Sorted sequence determined after 4 relations: ABCD. //在第几个关系是就可以确定关系 输出关系 Inconsistency found after 2 relations. //在第几个关系时 出现矛盾 Sorted sequence cannot be determined. //无法确定关系 Source |
文字信息来自:http://www.cnblogs.com/pushing-my-way/archive/2012/08/23/2652033.html
题意:给你一些大写字母间的偏序关系,然后让你判断能否唯一确定它们之间的关系,或者所给关系是矛盾的,或者到最后也不能确定它们之间的关系。
分析:
用拓扑排序:
1.拓扑排序可以用栈来实现,每次入栈的是入度为0的节点。
1.拓扑排序的结果一般分为三种情况:1、可以判断 2、有环出现了矛盾 3、条件不足,不能判断.
2.这道题不仅需要判断这三种情况,而且还要判断在处理第几个关系时出现前两种情况,对于本道题来说三种情况是有优先级的。前两种情况是平等的谁先出现先输出谁的相应结果,对于第三种情况是在前两种情况下都没有的前提下输出相应结果的.
#include <iostream>
#include <cstdlib>
#include <stack>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 30;
int n, m;
int graph[N][N], indu[N], list[N]; //graph[i][j] ==1 表示 i<j indu[i]表示 i 的入度, list储存输出顺序
int toopsort()
{
int tmp[N]; //为了不影响indu数组 这里把indu数组复制到tmp数组中
memcpy(tmp,indu,sizeof(indu));
stack<int> s;
while(!s.empty())
s.pop();
for( int i = 0;i < n;i++ )
{
if( tmp[i]==0 )
s.push(i); //如果入度为0的点大于1 则 不确定关系
}
int flag = 0;
int j = 0;
while(!s.empty())
{
if( s.size()>1 ) //判断<span style="font-family: Arial, Helvetica, sans-serif;">入度为0的点是否大于1</span>
flag = 1;
int t = s.top();
s.pop();
list[j++] = t;
for( int i = 0;i < n;i++ )
{
if( graph[t][i]==1 ) //t和i存在关系
if( --tmp[i]==0 ) // i 的入度减1, 此时 如果入度为0 则进栈
s.push(i);
}
}
if( j!=n ) //you huan //只有j==n的时候才说明不存在环
return 1;
else if( flag ) //no sure //在没有环的情况下 判断时候能够确定大小关系
return 2;
else
return 0; //上述两种情况都不存在
}
int main()
{
while(scanf("%d%d",&n,&m)&&n&&m)
{
getchar(); //读掉回车键
char a, b;
int flag1 = 0; //flag1 flag2 表示变量 控制输出;
int flag2 = 0;
memset(graph,0,sizeof(graph)); //初始化
memset(indu,0,sizeof(indu));
for( int i = 1;i <= m;i++ )
{
scanf("%c<%c",&a,&b);
getchar(); //读掉回车键
if( !flag1&&!flag2 ) //还没有输出过 进行下面的判断
{
if( graph[b-'A'][a-'A']==1 ) //存在环
{
printf("Inconsistency found after %d relations.",i);
flag1 = 1; //表示变量flag1改变
continue;
}
if( graph[a - 'A'][b - 'A']==0 ) //防止重复计算入度
{
graph[a - 'A'][b - 'A'] = 1;
indu[b-'A']++;
}
int tmp = toopsort(); //拓扑排序
if( tmp==1 ) //有环存在
{
printf("Inconsistency found after %d relations.",i);
flag1 = 1;
}
else if( tmp==0 ) //能够确定关系
{
flag2= 1; //标志变量flag2改变
printf("Sorted sequence determined after %d relations: ",i);
for( int j = 0;j < n;j++ )
{
printf("%c",list[j]+'A');
}
printf(".");
}
}
}
if( !flag1&&!flag2 ) //没有环 没有确定关系 就剩下无法确定了
{
printf("Sorted sequence cannot be determined.");
}
printf("\n");
}
return 0;
}