题目大意:

    对于给定的前n个字母( A-... ),给出可能的字母间的偏序,问是否能确定构成一个线性序T,如果能或不能,则给出最早能做出判断的偏序在第几个。否则说明不可判。

    这道题有点犀利,弄了半个晚上。一开始思维没打开,找不到思路,最后想到判断可达性的复杂度不可能比DFS传递闭包更好,因此果断改变思路。可以顺序读入每个偏序,对于每次读入,构造一次拓扑排序,那么在第几个偏序出解,结果就在第几。

    注意容易出现的逻辑错误,首先就是“判断是否能构成T序”的优先级高于T是否唯一,也就是说当出现多个可随意次序的点时,不能马上输出不唯一,需要将拓扑排序做完以保证没有成环,判环优先级更高。

    算法可以顺序读入偏序,随之做拓扑拆边,当遇到栈尺寸大于1(多个不可比),不可比标记置一。拓扑结束后,若成环,则输出成环,否则输出T唯一或继续读入偏序(当前不唯一)。若始终不成环且不唯一,最终结果自然不唯一。

4 4
A<B
C<B
D<B
B<A

Inconsistency found after 4 relations.

 1#include<cstdio>
 2#include<cstdlib>
 3#include<cstring>
 4#include<stack>
 5using namespace std;
 6int g[26][26],degree[26],degreeR[26],path[26];
 7bool ring,more;
 8int n,m;
 9int main(){
10    int i,j,k,t;
11    char u,v;
12    int ele;
13    bool sure,unsure;
14    while(scanf("%d%d",&n,&m),n|m){
15        memset(g,0,sizeof(g));
16        memset(degreeR,0,sizeof(degreeR));
17        sure = false;
18        for(getchar(),i=0;i<m;i++){
19            scanf("%c<%c",&u,&v);getchar();
20           
21            g[ u-'A' ][ v-'A' ]=1;
22            degreeR[ v-'A' ]++;
23            stack<int> _sta;
24            for(j=0;j<n;j++if( degreeR[j] == 0 ) _sta.push(j);
25
26            for(j=0;j<n;j++) degree[j]=degreeR[j];
27            more=false;
28            ring=false;
29            for(j=0;j<n;j++){
30               if( _sta.size()>1 ) more=true;   // unsure
31               if( _sta.empty() ){ ring=truebreak; }  // ring
32               ele = _sta.top(); _sta.pop();
33               path[j]=ele;
34               for(k=0;k<n;k++){
35                  if( g[ele][k]!=0 && --degree[k] == 0 ) {  _sta.push(k); }
36               }

37            }

38
39            if( j == n && more == false){
40                printf("Sorted sequence determined after %d relations: ",i+1);
41                for(j=0;j<n;j++) printf("%c",'A'+path[j]);   printf(".\n");
42                sure=true;
43                break;
44            }

45            else if( ring == true ){ printf("Inconsistency found after %d relations.\n",i+1); sure=truebreak; }
46        }

47        if( sure == false ) printf("Sorted sequence cannot be determined.\n");
48        for(t=i+1;t<m;t++){ scanf("%c<%c",&u,&v); getchar(); }
49    }

50    return 0;
51}

52