拓扑排序,对有环、多种排序、唯一排序分情况即可
1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <cstdlib> 5 #include <cmath> 6 #include <map> 7 #include <algorithm> 8 #include <list> 9 #include <ctime> 10 #include <set> 11 #include <cstring> 12 #include <queue> 13 #include <cstdio> 14 #include <stack> 15 using namespace std; 16 /*==================================================*\ 17 | 拓扑排序 18 | INIT:edge[][] 置为图的邻接矩阵;count[0…i…n-1]: 顶点i 的入度. 19 | 和TopoOrder实现的原理是一样的,只是没有用count。 20 \*==================================================*/ 21 const int V = 30; 22 int countk[V]; 23 int edge[V][V]; 24 int topres[V]; 25 int n; 26 #define CLR(arr, what) memset(arr, what, sizeof(arr)) 27 /* 28 1:有环 29 0:ok 30 -1:不确定 31 */ 32 int TopOrder_easy() { 33 int i; 34 stack<int> sh; 35 int ct = 0; 36 CLR(countk, 0); 37 for (i = 0; i < n; ++i) { 38 for (int j = 0; j < n; j++) { 39 if (1 == edge[i][j]) { 40 countk[j] += 1; 41 } 42 } 43 } 44 for (i = 0; i < n; ++i) 45 if (countk[i] == 0) { // 下标模拟堆栈 46 sh.push(i); 47 } 48 49 for (i = 0; i < n; ++i) { 50 if (sh.empty()) { 51 return 1; 52 } else { 53 if (sh.size() > 1) 54 ct = 1; 55 int j = sh.top(); 56 sh.pop(); 57 topres[i] = j; 58 for (int k = 0; k < n; ++k) 59 if (edge[j][k] && (--countk[k]) == 0) { 60 sh.push(k); 61 } 62 } 63 } 64 if (ct > 0) 65 return -1; 66 return 0; 67 } 68 void addnode(int u, int v) { 69 edge[u][v] = 1; 70 } 71 void printres() { 72 char t; 73 for (int i = 0; i < n; i++) { 74 t = topres[i] + 'A'; 75 cout << t; 76 } 77 } 78 void eat_useless(int numt){ 79 string t; 80 for(int i=0;i<numt;i++){ 81 cin>>t; 82 } 83 } 84 int main() { 85 int num, judge; 86 char t[4]; 87 cin >> n >> num; 88 while (n || num) { 89 CLR(edge, 0); 90 int a; 91 for (a = 0; a < num; a++) { 92 scanf("%s",t); 93 int u = t[0] - 'A'; 94 int v = t[2] - 'A'; 95 addnode(u, v); 96 judge = TopOrder_easy(); 97 if (-1 == judge && (num - 1) == a) { 98 cout << "Sorted sequence cannot be determined.\n"; 99 } else if (0 == judge) { 100 cout << "Sorted sequence determined after " << a + 1 101 << " relations: "; 102 printres(); 103 cout << ".\n"; 104 eat_useless(num-a-1); 105 break; 106 } else if (1 == judge) { 107 cout << "Inconsistency found after " << a + 1 108 << " relations.\n"; 109 eat_useless(num-a-1); 110 break; 111 } 112 } 113 if (0 == num) { 114 cout << "Sorted sequence cannot be determined.\n"; 115 } 116 scanf("%d%d", &n, &num); 117 } 118 return 0; 119 }