77 lines
2.7 KiB
C++
77 lines
2.7 KiB
C++
#include <bits/stdc++.h>
|
||
using namespace std;
|
||
|
||
const int N = 26;
|
||
|
||
int n, m;
|
||
int g[N][N];
|
||
bool st[N];
|
||
|
||
// 求传递闭包
|
||
void floyd() {
|
||
for (int k = 0; k < n; k++)
|
||
for (int i = 0; i < n; i++)
|
||
for (int j = 0; j < n; j++)
|
||
g[i][j] |= g[i][k] && g[k][j];
|
||
}
|
||
|
||
int check() {
|
||
for (int i = 0; i < n; i++)
|
||
if (g[i][i]) return 2; // 矛盾
|
||
|
||
for (int i = 0; i < n; i++)
|
||
for (int j = 0; j < i; j++)
|
||
if (!g[i][j] && !g[j][i]) // 待继续
|
||
return 0;
|
||
|
||
return 1; // 找到顺序
|
||
}
|
||
|
||
string getorder() { // 升序输出所有变量
|
||
char s[26];
|
||
for (int i = 0; i < n; i++) {
|
||
int cnt = 0;
|
||
// f[i][j] = 1表示i可以到达j (i< j)
|
||
for (int j = 0; j < n; j++) cnt += g[i][j]; // 比i大的有多少个
|
||
// 举个栗子:i=0,表示字符A
|
||
// 比如比i大的有5个,共6个字符:ABCDEF
|
||
// n - cnt - 1 = 6-5-1 = 0,也就是A放在第一个输出的位置上, 之所以再-1,是因为下标从0开始
|
||
s[n - cnt - 1] = i + 'A';
|
||
}
|
||
|
||
// 转s字符数组为字符串
|
||
string res;
|
||
for (int i = 0; i < n; i++) res = res + s[i];
|
||
return res;
|
||
}
|
||
|
||
int main() {
|
||
while (cin >> n >> m, n || m) {
|
||
memset(g, 0, sizeof g); // 邻接矩阵
|
||
int type = 0, t; // type: 0=还需要继续给出条件 1=找到了顺序 2=存在冲突
|
||
// t:在第几次输入后找到了顺序,不能中间break,因为那样会造成数据无法完成读入,后续的操作无法进行,只能记录下来当时的i
|
||
for (int i = 1; i <= m; i++) {
|
||
char s[5];
|
||
cin >> s;
|
||
int a = s[0] - 'A', b = s[2] - 'A'; // A->0,B->1,...,Z->25完成映射关系
|
||
|
||
if (!type) { // 如果不存在矛盾,就尝试找出大小的顺序
|
||
g[a][b] = 1; // 有边
|
||
floyd(); // 求传递闭包
|
||
type = check(); // 检查是不是存在矛盾,或者找到了完整的顺序
|
||
if (type > 0) t = i; // 如果找到了顺序,或者发现了矛盾,记录是第几次输入后发现的
|
||
}
|
||
// 即使存在矛盾,也需要继续读入,直到本轮数据读入完成
|
||
}
|
||
|
||
if (!type)
|
||
puts("Sorted sequence cannot be determined.");
|
||
else if (type == 2)
|
||
printf("Inconsistency found after %d relations.\n", t);
|
||
else {
|
||
string ans = getorder(); // 输出升序排列的所有变量
|
||
printf("Sorted sequence determined after %d relations: %s.\n", t, ans.c_str());
|
||
}
|
||
}
|
||
return 0;
|
||
} |