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;
}