SCOI2008 天平
用floyd跑差分约束==
因为砝码大小只有1、2、3 所以未知时最大差值为2 最小差值为-2
由\(A+B>C+D\)可以转为\(A-C>D-B\) 然后就挨个判断就好了
注意判断等于时的条件
#include<bits/stdc++.h>
using namespace std;
#define Max(x,y) ((x)>(y)?(x):(y))
#define Min(x,y) ((x)<(y)?(x):(y))
const int N=50+10,M=1e6+10,inf=0x3f3f3f3f;
int n,A,B,c1,c2,c3,mx[N][N],mn[N][N];
char opt[N];
int main(){
freopen("in.txt","r",stdin);
scanf("%d%d%d",&n,&A,&B);
for(int i=1;i<=n;++i){
scanf("%s",opt+1);mx[i][i]=mn[i][i]=0;
for(int j=1;j<=n;++j)
if(j!=i){
if(opt[j]=='-') mn[i][j]=-2,mx[i][j]=-1;
else if(opt[j]=='+') mn[i][j]=1,mx[i][j]=2;
else if(opt[j]=='=') mx[i][j]=mn[i][j]=0;
else mn[i][j]=-2,mx[i][j]=2;
}
}
for(int k=1;k<=n;++k)
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
mn[i][j]=Max(mn[i][j],mn[i][k]+mn[k][j]),
mx[i][j]=Min(mx[i][j],mx[i][k]+mx[k][j]);
for(int i=1;i<=n;++i)
if(i!=A&&i!=B)
for(int j=i+1;j<=n;++j)
if(j!=A&&j!=B){
if(mn[A][i]>mx[j][B]||mn[B][i]>mx[j][A]) ++c1;
if(mn[i][A]>mx[B][j]||mn[i][B]>mx[A][j]) ++c3;
if(mn[A][i]==mx[A][i]&&mn[j][B]==mx[j][B]&&mn[A][i]==mn[j][B])++c2;
else if(mn[B][i]==mx[B][i]&&mn[j][A]==mx[j][A]&&mn[B][i]==mn[j][A])++c2;
}
printf("%d %d %d",c1,c2,c3);
return 0;
}