#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N = 26;
int n, m;
bool g[N][N], d[N][N];
bool st[N];
void floyd() {
memcpy(d, g, sizeof d);
for (int k = 0; k < n; k ++)
for (int i = 0; i < n; i ++)
for (int j = 0; j < n; j ++)
// i k满足关系,k j满足关系,传递可知 i j 也满足关系
d[i][j] |= d[i][k] && d[k][j];
// if (d[i][k] == d[k][j]) d[i][j] = 1;
}
int check() {
for (int i = 0; i < n; i ++)
if (d[i][i]) // 自己跟自己的关系是小于,那就离谱,矛盾了,跳出
// 一次floyd算法可以直接更新出所有点的关系,如果有矛盾会被递推到d[i][i] = 1
// 如 A < B ,B < C 那么执行floyd的时候会更新 -> d[A][C] = 1
// 如果此时输入了一个矛盾的关系: C < A -> d[C][A] = 1
// d[A][A] |= d[A][C] && d[C][A] -> d[A][A] = 1
return 2;
for (int i = 0; i < n; i ++)
for (int j = 0; j < i; j ++)
if (!d[i][j] && !d[j][i]) // 但凡存在一对数, 他们之间没有任何关系
// 那就表明不能确定他们之间的关系
return 0;
// 否则是可以确定关系的
return 1;
}
char get_min() {
for (int i = 0; i < n; i ++)
if (!st[i]) { // 第i个变量是否已经输出,没有的话才做检查
bool flag = true; // 可以输出
for (int j = 0; j < n; j ++) // 遍历剩下所有的数
if (!st[j] && d[j][i]) {
// 如果找到一个j没输出居然还比i小,那i不可能输出
flag = false;
break; // break
}
if (flag) { // 如果没找到比i小的,那么i肯定是还没输出的变量中最小的
st[i] = true; // 标记一下
return 'A' + i; // 输出i
}
}
}
// Floyd算法可以在n三方的时间复杂度内, 求出一个图的传递闭包
int main() {
while (cin >> n >> m, n || m) {
memset(g, 0, sizeof g);
int type = 0, t; // 一共种情况
for (int i = 1; i <= m; i ++) {
char str[5];
cin >> str;
int a = str[0] - 'A', b = str[2] - 'A'; // 把两变量存下来
if (!type) { // 如果当前变量的关系是不能确定的
g[a][b] = 1; // 关系也存下来
floyd(); // 每读入一段关系,就用一次floyd,更新一下闭包
type = check(); // 检查一下闭包
if (type) t = i; // 每读入一对关系, 如果不是不能确定那就是读入成功
}
}
if (!type) puts("Sorted sequence cannot be determined.");
else if (type == 2) printf("Inconsistency found after %d relations.\n", t);
else {
memset(st, 0, sizeof st);
printf("Sorted sequence determined after %d relations: ", t);
for (int i = 0; i < n; i ++) printf("%c", get_min());
printf(".\n");
}
}
return 0;
}
check()那里为什么不能写小于n?