这道题本质上是Floyd求传递闭包,所谓传递闭包,就是这个样子,非常的简单,即在一个传递闭包中元素之间都有某种关系。
这道题数据范围很小,因此我们可以开一个邻接矩阵,floyd[i][j]就表示i>j。当我们判断的时候很简单,当floyd[i][j]==floyd[j][i]==1时,就矛盾了,当floyd[i][j]==0且floyd[j][i]==0时,就说明i,j的大小关系不能确定。知道了这两个后,本题就不难了。首先去枚举前t个不等式组,每一次加一条边后求传递闭包。之后以此判断矛盾,排序成功,当t组枚举完之后,判断是否可以排序即可。
参考代码如下:
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 struct node 6 { 7 int nodee,num; 8 }f[10001]; 9 int floyd[127][127],n,m,a1[100001],b1[100001],c1[100001]; 10 char a,b,c; 11 bool cmp(node a,node b) 12 { 13 return a.num<b.num; 14 } 15 int main() 16 { 17 bool flag; 18 int pd=12345678; 19 while(1) 20 { 21 cin>>n>>m; 22 if(!n&&!m)return 0; 23 flag=0; 24 pd=0; 25 memset(floyd,0,sizeof(floyd)); 26 for(int t=1;t<=m;t++) 27 { 28 cin>>a>>b>>c; 29 int x=a-'A'+1,y=c-'A'+1; 30 f[x].nodee=x;f[x].num=0; 31 f[y].num=0;f[y].nodee=y; 32 if(flag)continue; 33 if(b=='<')floyd[x][y]=1; 34 else floyd[y][x]=1; 35 for(int k=1;k<=n;k++) 36 { 37 for(int i=1;i<=n;i++) 38 { 39 for(int j=1;j<=n;j++) 40 { 41 floyd[i][j]|=floyd[i][k]&floyd[k][j]; 42 } 43 } 44 } 45 for(int i=1;i<=n;i++) 46 { 47 for(int j=i+1;j<=n;j++) 48 { 49 if(floyd[i][j]&&floyd[j][i]) 50 { 51 flag=1; 52 cout<<"Inconsistency found after "<<t<<" relations."<<endl; 53 break; 54 } 55 } 56 if(flag)break; 57 } 58 if(flag)continue; 59 int fss=1; 60 for(int i=1;i<=n;i++) 61 { 62 if(pd!=0&&pd!=12345678) 63 { 64 fss=0; 65 break; 66 } 67 for(int j=i+1;j<=n;j++) 68 { 69 if(!floyd[i][j]&&!floyd[j][i]) 70 { 71 fss=0; 72 if(t==m) 73 { 74 cout<<"Sorted sequence cannot be determined."<<endl; 75 flag=1; 76 break; 77 } 78 } 79 } 80 if(flag)break; 81 } 82 if(flag)continue; 83 if(fss==1) 84 { 85 pd=t; 86 for(int i=1;i<=n;i++) 87 { 88 for(int j=1;j<=n;j++) 89 { 90 if(floyd[i][j]&&i!=j)f[j].num++; 91 } 92 } 93 sort(f+1,f+1+n,cmp); 94 cout<<"Sorted sequence determined after "<<pd<<" relations: "; 95 for(int i=1;i<=n;i++)cout<<char(f[i].nodee+'A'-1); 96 cout<<"."<<endl; 97 flag=1; 98 } 99 } 100 } 101 }