题意:现在有多个大写字母(不一定连续),给出字母之间的大小关系,问到第几个关系时就能判断有唯一大小排序或出现矛盾,或是有多个合理排序,若有唯一排序,则输出它。

拓扑序,只不过坑爹的是如果关系处理到一半就已经能确定序列了,即使后面的关系出现矛盾也不用管了,直接可以输出可行。其他的就是做拓扑排序了,只不过要每次加入一组关系之后做一次拓扑序。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<queue>
 4 using namespace std;
 5 
 6 int id[27],ma[27][27],n,tmp[27],ans[27];
 7 
 8 int topo(){
 9     memcpy(tmp,id,sizeof(tmp));
10     queue<int>q;
11     for(int i=1;i<=n;++i)if(!tmp[i])q.push(i);
12     int cnt=0;
13     bool f=1;
14     while(!q.empty()){
15         int u=q.front();
16         q.pop();
17         ans[++cnt]=u;
18         if(!q.empty())f=0;
19         for(int i=1;i<=n;++i){
20             if(i!=u&&ma[u][i]){
21                 tmp[i]--;
22                 if(!tmp[i])q.push(i);
23             }
24         }
25     }
26     if(cnt!=n)return 0;
27     if(f)return 1;
28     return -1;
29 }
30 
31 char s[10];
32 
33 int main(){
34     int m;
35     while(scanf("%d%d",&n,&m)!=EOF&&n+m){
36         bool f=0;
37         memset(id,0,sizeof(id));
38         memset(ma,0,sizeof(ma));
39         for(int i=1;i<=m;++i){
40             scanf("%s",s);
41             if(f)continue;
42             int a=s[0]-'A'+1;
43             int b=s[2]-'A'+1;
44             ma[a][b]=1;
45             id[b]++;
46             int ff=topo();
47             if(!ff){
48                 printf("Inconsistency found after %d relations.\n",i);
49                 f=1;
50             }
51             else if(ff==1){
52                 printf("Sorted sequence determined after %d relations: ",i);
53                 for(int j=1;j<=n;++j)printf("%c",'A'+ans[j]-1);
54                 printf(".\n");
55                 f=1;
56             }
57         }
58         if(!f)printf("Sorted sequence cannot be determined.\n");
59     }
60     return 0;
61 }
View Code