链接
https://www.acwing.com/problem/content/345/
题目
给定 n 个变量和 m 个不等式。其中 n 小于等于26,变量分别用前 n 的大写英文字母表示。
不等式之间具有传递性,即若 A>B 且 B>C ,则 A>C。
请从前往后遍历每对关系,每次遍历时判断:
如果能够确定全部关系且无矛盾,则结束循环,输出确定的次序;
如果发生矛盾,则结束循环,输出有矛盾;
如果循环结束时没有发生上述两种情况,则输出无定解。
输入格式
输入包含多组测试数据。
每组测试数据,第一行包含两个整数n和m。
接下来m行,每行包含一个不等式,不等式全部为小于关系。
当输入一行0 0时,表示输入终止。
输出格式
每组数据输出一个占一行的结果。
结果可能为下列三种之一:
如果可以确定两两之间的关系,则输出 "Sorted sequence determined after t relations: yyy...y.",其中't'指迭代次数,'yyy...y'是指升序排列的所有变量。
如果有矛盾,则输出: "Inconsistency found after t relations.",其中't'指迭代次数。
如果没有矛盾,且不能确定两两之间的关系,则输出 "Sorted sequence cannot be determined."。
数据范围
2≤n≤26,变量只可能为大写字母A~Z。
输入样例:
4 6
A<B
A<C
B<C
C<D
B<D
A<B
3 2
A<B
B<A
26 1
A<Z
0 0
输入样例:
输出样例:
输入样例:
Sorted sequence determined after 4 relations: ABCD.
Inconsistency found after 2 relations.
Sorted sequence cannot be determined.
思路
传递闭包:
由:a>b,b>c , 可知:a>c。当a到b,b到c分别有一条边时,可以向a到c连一条边。求传递闭包的过程用flody非常方便。
在每增加一个条件时连一条边并求一次传递闭包,当有一个点可以自己走到自己,说明存在某个例子:a>b,a<b,此时无解。当每个点对之间都只存在一条边时说明已经有解。对于每个点可以被多少个点到达,就可以说明他的大小。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=26;
bool g[N][N],d[N][N];
char s[5];
int n,m;
int st[N];
void flody(){
memcpy(g,d,sizeof d);
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(){ //0未确定,1得解, 2无解
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;
}
void get_min(){
for(int i=0;i<n;++i){
if(st[i]) continue;
bool flag=0;
for(int j=0;j<n;++j){
if(!st[j]&&g[j][i]){
flag=1;
break;
}
}
if(!flag){
cout<<(char)(i+'A');
st[i]=1;
return ;
}
}
}
int main(){
while(cin>>n>>m,m||n){
memset(st,0,sizeof st);
memset(d,0,sizeof d);
int type=0,t=0;
for(int i=1;i<=m;i++){
cin>>s;
int x=s[0]-'A',y=s[2]-'A';
if(!type){
d[x][y]=1;
flody();
type=check();
if(type) t=i;
}
}
if(type==1){
cout<<"Sorted sequence determined after "<<t<<" relations: ";
int tn=n;
while(tn--){
get_min();
}
cout<<".
";
}
else if(type==2)
cout<<"Inconsistency found after "<<t<<" relations.
";
else
cout<<"Sorted sequence cannot be determined.
";
}
return 0;
}