前置知识:拓扑排序
详细注释都在代码里
1 //该题题意明确,就是给定一组字母的大小关系判断他们是否能组成唯一的拓扑序列。
2 //是典型的拓扑排序,但输出格式上确有三种形式:
3
4 // 1.该字母序列有序,并依次输出;
5
6 // 2.该序列不能判断是否有序;
7
8 // 3.该序列字母次序之间有矛盾,即有环存在。
9
10 // 而这三种形式的判断是有顺序的:先判断是否有环(3),
11 //再判断是否有序(1),最后才能判断是否能得出结果(2)。
12 //注意:对于(2)必须遍历完整个图,而(1)和(3)一旦得出结果,
13 //对后面的输入就不用做处理了。
14
15 //有一个问题,我不太清楚,就是在确定有序之后,就直接输出答案,
16 //对右面的输入也不再处理,但是后面的输入可以让其成为环的话又就会
17 //让其成为环,所以我想这道题就是在确定有序之后,后面的数据,就都不要了。
18 //应该是这意思把
19 #include<cstdio>
20 #include<algorithm>
21 #include<string.h>
22 #include<math.h>
23 #include<queue>
24 using namespace std;
25 typedef long long ll;
26 const int maxn=1e2+10;
27 int G[30][30];
28 int in[30];
29 int q[30];
30 void init()
31 {
32 memset(G,0,sizeof(G)); //图
33 memset(in,0,sizeof(in)); //入度
34 }
35 int Toposort(int n)
36 {
37 int aim;int cot=0;
38 int tmpin[30];
39 int flag=1; //1的时候表示有序
40 for(int i=1;i<=n;i++) tmpin[i]=in[i]; //将入度复制到tmpin里面来
41 for(int i=1;i<=n;i++){
42 int num=0;
43 for(int j=1;j<=n;j++)
44 if(!tmpin[j]) num++,aim=j; //这里来判断入度数量,aim是入度为0的那个点
45 //这里如果出现多个入度,就会选择最后面那个先进行操作;
46 if(!num) return 0; //有环;
47 if(num>1) flag=-1; //无序
48 q[cot++]=aim;
49 tmpin[aim]=-1;
50 for(int j=1;j<=n;j++)
51 if(G[aim][j]) tmpin[j]--;
52 }
53 return flag;
54
55 }
56 int main()
57 {
58 int n,m;
59 while(scanf("%d%d",&n,&m)!=EOF){
60 if(!n&&!m) break;
61 init();
62 char str[5];
63 int flag=0;
64 for(int i=1;i<=m;i++){
65 scanf("%s",str);
66 if(flag) continue;
67 int l=str[0]-'A'+1;
68 int r=str[2]-'A'+1;
69 G[l][r]=1;
70 in[r]++;
71 int judge=Toposort(n);
72 //有环
73 if(!judge) printf("Inconsistency found after %d relations.\n",i),flag=1;
74 if(judge==1){ //有序
75 printf("Sorted sequence determined after %d relations: ",i);
76 for(int j=0;j<n;j++)
77 printf("%c",q[j]+'A'-1);
78 printf(".\n");
79 flag=1;
80 }
81 }
82 //无序
83 if(!flag) printf("Sorted sequence cannot be determined.\n");
84 }
85 return 0;
86 }