排序

链接

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;
}
原文地址:https://www.cnblogs.com/jjl0229/p/12808623.html