int vis[100], ma[100][100], in[100]; string s; int n, m;
inttopo(){ // 每加进一个条件就要拓扑一次 s = ""; //拓扑序列, 要是加进某一个条件之后正好完成了此拓扑排序。 将其输出即可, 所以其为全局变量 int now[100]; // 储存此时的所有边的入度 memset(vis, 0, sizeof vis); int to = 0, f = 1, p; // to 入度为0的点的个数, f 标记这些字母是否完成了拓扑排序 // p 指向最后一个入度为0的点, 在下面可以看到, for (int i = 1; i <= n; i++){ now[i] = in[i]; // in 入度 } for (int i = 1; i <= n; i++){ to = 0; // 每一次循环都要找入度为0的点 for (int j = 1; j <= n; j++){ if (!now[j] && !vis[j]){ // to++; p = j; } } if (to == 0) //如果没有入度为0的点, 那就出现了矛盾 return0;
if (to >= 2) // 大于等于两个就有多种情况。说明现在还未排好序, 所以标记个2 f = 2; for (int i = 1; i <= n; i++){ if (ma[p][i]) now[i]--; // 正常套路, 让与p有关的边的入度减一 } vis[p] = 1; s += p + 'A' - 1; } return f; // 返回1或2 具体看下
}
intmain(){ char a, b, f; while(cin >> n >> m) { if (!n && !m) break; memset(in, 0, sizeof in); int flag = 1; memset(ma, 0, sizeof ma); for (int i = 1; i <= m; i++){ cin >> a >> f >> b; if(f == '>') swap(a, b); int x = a - 'A' + 1; //这个处理技巧真的妙, 妙不可言 int y = b - 'A' + 1; if (!ma[x][y]){ ma[x][y] = 1; in[y]++; } x = topo(); // 这是返回值就排上用场了 if (flag){ // 当flag == 0时, 代表着结果已出, 其他就没必要输出了 if (x == 0){ flag = 0; // 标记flag 这个也很妙呀 printf("Inconsistency found after %d relations.\n", i); } elseif (x == 1){ flag = 0; printf("Sorted sequence determined after %d relations: ", i); cout << s << ".\n"; } } } if (flag) puts("Sorted sequence cannot be determined."); } return0; }