d(i,j)含义为i<j,那么根据Floyd特点每次利用一个中间点更新其他值,那么比如 i<k,k<j推出i<j ,根据这个特点更新。
每次读入一对关系,然后跑一边Floyd,再去判断一下是否矛盾,有未确定的关系
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define x first
#define y second
typedef pair<int,int> PII;
const int N=30;
int n,m,k,ans;
PII q[N];
bool d[N][N],g[N][N];
bool vis[N];
void floyed() {
memcpy(d,g,sizeof d);//将已知的关系复制到d数组中
for(int k=0; k<n; k++) {
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++) {
if(!d[i][j])d[i][j]=d[i][k]&d[k][j]; //传递包闭
}
}
}
}
int check() {//检查是否合法
for(int i=0; i<n; i++) if(d[i][i])return 2; //矛盾
for(int i=0; i<n; i++) {
for(int j=0; j<n; j++)
if(i!=j)
if(!d[i][j]&&!d[j][i]) return 0;//i和j之间还不存在关系
}
return 1;
}
char get_min() { //每次取出最小值
for(int i=0; i<n; i++) {
if(!vis[i]) {
bool flag=true;
for(int j=0; j<n; j++) { //判断是否最小
if(!vis[j]&&d[j][i]) { //存在j没有出队过,并且j<i
flag=false;
break;
}
}
if(flag) {
vis[i]=1;
return 'A'+i;
}
}
}
}
int main() {
while(cin>>n>>m,n||m) {
memset(g,0,sizeof g);
int type=0,t;//t记录轮次,type记录类型
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;//a<b
floyed();//更新之前关系
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(vis, 0, sizeof vis);
printf("Sorted sequence determined after %d relations: ", t);
for(int i = 0; i < n; i ++) printf("%c", get_min());
printf(".\n");
}
}
return 0;
}