You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
3.8 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 30, M = N * N;
int n, m;
int a[1050], b[1050]; // a[i]<b[i]
char s[N]; // 输入的偏序关系
int in[N], ind[N];
int d[N], dl;
// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
/*
(1) n,
(2) n,2
(3) n,
*/
int topsort() {
queue<int> q;
bool flag = 0;
for (int i = 0; i < n; i++) // 枚举每个节点,入度为零的入队列
if (in[i] == 0) q.push(i);
while (q.size()) {
/*
使2
n
2
*/
if (q.size() > 1) flag = 1;
int u = q.front();
q.pop();
d[++dl] = u; // 按出队列的顺序来记录由小到大的关系
for (int i = h[u]; ~i; i = ne[i]) {
int j = e[i];
if (--in[j] == 0) q.push(j);
}
}
// 有环
if (dl < n) return 1;
// 不确定
if (dl == n && flag) return 2;
// 已确定
return 3;
}
int main() {
// n个变量m个不等式也就是n 个节点m条边
while (~scanf("%d%d", &n, &m) && n | m) {
// 多组测试数据,需要初始化
// 链式前向星
memset(h, -1, sizeof h);
idx = 0;
// 入度数组初始化
memset(ind, 0, sizeof ind);
// 输入大小关系,'A'->0,...,'Z'->25
for (int i = 1; i <= m; i++) {
scanf("%s", s); // 通用格式 类似于: B<C
a[i] = s[0] - 'A', b[i] = s[2] - 'A'; // 用两个数组a[],b[]记录关系,表示a[i]<b[i]
}
bool flag = 1; // 是不是已经找出了全部的大于关系序列
// 逐个讨论每个大小关系
for (int i = 1; i <= m; i++) {
dl = 0; // 拓扑序输出数组清零
add(a[i], b[i]); // 建图
ind[b[i]]++; // 记录b[i]入度
// 因为topsort会在过程中执行--ind[j]而此图和入度的值后面还要继续用不能让topsort改坏了
// 复制出来一个临时的入度数组in[]
memcpy(in, ind, sizeof ind);
// 每输入一个关系表达式就topsort一次
int res = topsort();
// 拓扑序唯一
if (res == 3) {
printf("Sorted sequence determined after %d relations: ", i);
for (int j = 1; j <= dl; j++) printf("%c", d[j] + 'A');
puts(".");
flag = 0;
break;
} else if (res == 1) { // 有环
printf("Inconsistency found after %d relations.\n", i);
flag = 0;
break;
}
}
// 最终还是没有发现矛盾,也没有输出唯一序,说明条件还是不够啊,顺序无法确定
if (flag) puts("Sorted sequence cannot be determined.");
}
return 0;
}