题意:给你n个大写字母,m对大小关系,根据他给的关系推测是否有大小矛盾的情况。如果有矛盾的就输出是在第几组关系时矛盾;如果不矛盾,判断只需要前t对组关系就能推测出他们从小到大的排序;如果没有以上两种情况就输入无法确定。
思路:对于每输入一对关系就跑一次floyd判断一遍,如果能推测出他们的关系,那么就跑一边拓扑排序求出他们从小打到的排序情况;如果有矛盾的关系就直接输出是在第几组关系时矛盾;如果没有以上情况就输出无法确定。
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int N = 26 + 10;
int n, m, dis[N][N], in[N], out[N];
char a, b, c;
vector<int> v[N];
int main() {
while(cin >> n >> m && (n + m)) {
memset(dis, 0, sizeof dis);
for(int i = 0; i < N; i++)
v[i].clear();
int wz = -1, md = -1;
for(int x, y, s = 0; s < m; s++) {
cin >> a >> c >> b;
x = a - 'A' + 1;
y = b - 'A' + 1;
if(wz > 0)
continue;
dis[x][y] = 1;
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
dis[i][j] |= (dis[i][k] & dis[k][j]);
int f = 0;
memset(in, 0, sizeof in);
memset(out, 0, sizeof out);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) {
if(i != j && dis[i][j])
in[j]++, out[i]++;
if(i != j && dis[i][j] && dis[j][i]) {
md = s + 1;
wz = 100;
}
}
for(int i = 1; i <= n; i++)
if(in[i] + out[i] != n - 1)
f = 1;
if(f == 0)
wz = s + 1;
}
if(wz > 0 && wz != 100) {
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) {
if(i != j && dis[i][j])
v[i].push_back(j);
}
queue<int> q;
for(int i = 1; i <= n; i++) {
if(in[i] == 0)
q.push(i);
}
vector<int> ans;
while(!q.empty()) {
int d = q.front();
q.pop();
ans.push_back(d);
for(int i = 0; i < v[d].size(); i++) {
in[v[d][i]]--;
if(in[v[d][i]] == 0)
q.push(v[d][i]);
}
}
cout << "Sorted sequence determined after " << wz << " relations: ";
for(int i = 0; i < ans.size(); i++)
cout << (char)(ans[i] + 'A' - 1);
cout << "." << endl;
} else {
if(md > 0) {
cout << "Inconsistency found after " << md << " relations." << endl;
} else {
cout << "Sorted sequence cannot be determined." << endl;
}
}
}
return 0;
}