【POJ1094】Sorting it all out
题目链接:https://www.acwing.com/problem/content/345/
题目大意:给定 \(m\) 个不等式关系 , 确定变量间的大小关系 , 或找出不等式关系间的矛盾
solution
如果\(i < j\) , \(j < k\) , 则 \(i < k\) ,因此这些不等式关系间具有传递性 , 所以这是一道经典的传递闭包问题 ,可以用\(Floyd\) 传递关系
令 \(g[i][j] = 1\) 表示 \(i < j\) , \(g[i][j] = 0\) 表示 \(i \geq j\) 或不确定 , 其中\(g[i][j]\) |= \(g[i][k]\) & \(g[k][j]\) , 最后依次遍历 , 如果 \(g[i][j] = 1\) 且 \(g[j][i] = 1\) , 则发生矛盾 , 如果 \(g[i][j] = 0\) 且 \(g[j][i] = 0\) , 则无法确定 , 否则 , 可以确定 \(i\) 与 \(j\) 之间的唯一关系 , 输出时每次找到最小的输出并排除即可
时间复杂度: \(O(mn^2)\)
code
#include<bits/stdc++.h>
using namespace std;
template <typename T> inline void read(T &FF) {
int RR = 1; FF = 0; char CH = getchar();
for(; !isdigit(CH); CH = getchar()) if(CH == '-') RR = -RR;
for(; isdigit(CH); CH = getchar()) FF = FF * 10 + CH - 48;
FF *= RR;
}
inline void file(string str) {
freopen((str + ".in").c_str(), "r", stdin);
freopen((str + ".out").c_str(), "w", stdout);
}
const int N = 1e3 + 10;
char ai, bi, ci;
int pd[N][2], g[30][30], n, m;
int check(int xi) {
memset(g, 0, sizeof(g));
for(int i = 1; i <= xi; i++)
g[pd[i][0]][pd[i][1]] = true;
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
g[i][j] |= g[i][k] & g[k][j];
int flag = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(i != j) {
if(g[i][j] && g[j][i]) return false;
else if(!g[i][j] && !g[j][i]) flag = true;
}
else if(g[i][j] == 1) return false;
return flag + 1;
}
void print(int xi) {
printf("Sorted sequence determined after %d relations: ", xi);
int out[30] = {0};
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++)
if(!out[j]) {
int flag = 0;
for(int k = 1; k <= n; k++)
if(!out[k] && g[k][j]) {
flag = 1;
break;
}
if(!flag) {
cout << char(j + 'A' - 1), out[j] = 1;
break;
}
}
}
cout << "." << endl;
}
int main() {
//file("");
while(true) {
read(n), read(m);
if(!n && !m) break;
for(int i = 1; i <= m; i++) {
cin >> ai >> bi >> ci;
if(bi == '<') pd[i][0] = ai - 'A' + 1, pd[i][1] = ci - 'A' + 1;
else pd[i][1] = ai - 'A' + 1, pd[i][0] = ci - 'A' + 1;
}
int fg = 0;
for(int i = 1; i <= m; i++)
if(!check(i)) {
printf("Inconsistency found after %d relations.\n", i);
fg = 1; break;
}
else if(check(i) == 1) {
print(i);fg = 1; break;
}
if(fg) continue;
puts("Sorted sequence cannot be determined.");
}
return 0;
}