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; }