题面:
题意:
给定 n 个变量和 m 个不等式(不等式满足传递性),从前往后确定每对变量的关系,看是否有出现矛盾的情况。
题解:
传递性:设 ⊙ 是定义在集合 S 上的二元关系,若对于 a,b,cS,只要有a⊙b且b⊙c,那么必然有a⊙c,那么 ⊙ 具有传递性。而题目里给定的二元关系就是 > ,同时还得确定每对变量的关系,所以问题转换为求传递闭包。
对于传递闭包的题目,大部分的做法都是 floyd。代码中的 dis[i][j] 表示是否存在 i>j 这一组关系,全都初始化为正无穷。每当添加一对关系,就更新一下 dis 值,在没有出现矛盾的情况下,我们也没有必要跑完整的 floyd,只需要用这条边的两个端点分别作为中转点来更新其他点就行了,因为其他边(其他组关系)没变,用其他点作为中转点不会有任何更新。而对于像 dis[i][j]=dis[j][i]=1 或者 dis[i][i]=1 这种情况就属于矛盾。
代码:
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define eps 1e-10
#define lowbit(x) x&-x
#define int long long
#define INF 1e18
#define PII pair<int,int>
#define fi first
#define se second
#define il inline
il int read()
{
int x=0,f=0;
char ch=0;
while(!isdigit(ch))
{
f|=(ch=='-');
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return f?-x:x;
}
il void write(int x)
{
char num[30];
int cnt=0;
if(x==0) { putchar('0'); return; }
if(x<0)
{
putchar('-');
x=-x;
}
while(x>0)
{
num[cnt++]=x%10+'0';
x/=10;
}
while(cnt>0) putchar(num[--cnt]);
}
int n,m,dis[205][205];
PII ans[205];
il void floyd(int k)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
bool check()
{
for(int i=1;i<=n;i++)
{
int cnt=1;//自身本就确定
for(int j=1;j<=n;j++)
if(dis[i][j]!=INF)
cnt++;
ans[i]={cnt,i};//比他小的数量
for(int j=1;j<=n;j++)
if(i!=j&&dis[j][i]!=INF)//比他大的
cnt++;
if(cnt!=n) return 0;
}
sort(ans+1,ans+n+1);
return 1;
}
signed main()
{
while(cin>>n>>m&&n&&m)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dis[i][j]=INF;//dis[i][j]表示是否存在i>j这一组关系
int f=0;
for(int i=1;i<=m;i++)
{
char a,op,b;
cin>>a>>op>>b;//a<b
int x=a-'A'+1,y=b-'A'+1;
if((dis[x][y]!=INF&&!f)||(x==y))
{
//如果a>b或者a=b都不行
printf("Inconsistency found after %d relations.\n",i);
f=1;
}
dis[y][x]=1;//标记关系
floyd(x),floyd(y);//以新添加的关系为中点跑floyed,更新图
if(!f&&check())
{
//如果关系都确定了
printf("Sorted sequence determined after %d relations: ",i);
for(int i=1;i<=n;i++) cout<<char(ans[i].se+'A'-1);
printf(".\n");
f=1;
}
}
if(!f) printf("Sorted sequence cannot be determined.\n");
}
return 0;
}