bzoj1077: [SCOI2008]天平
题目链接
题解
利用查分约束
floyed求出差值的上下界
暴力
#include<bits/stdc++.h>
using namespace std;
inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-')f = -1; c = getchar();}
while(c <= '9' && c >= '0')x = x * 10 + c - '0' ,c = getchar();
return x * f;
}
const int maxn = 57;
int n ,A,B,mx[maxn][maxn],mn[maxn][maxn];
char ch[maxn];
int main() {
n = read(), A = read(), B = read();
for(int i = 1;i <= n;++ i) {
scanf("%s",ch + 1);
for(int j = 1;j <= n;++ j) {
if(ch[j] == '+') mn[i][j] = 1,mx[i][j] = 2;
else if(ch[j] == '-') mx[i][j] = -1,mn[i][j] = -2;
else if(ch[j] == '=') mx[i][j] = mn[i][j] = 0;
else {
mx[i][j] = 2; mn[i][j] = -2;
}
}
}
for(int k = 1;k <= n;++ k)
for(int i = 1;i <= n;++ i) {
for(int j = 1;j <= n;++ j) {
if(i == j || j == k || i == k) continue;
mn[i][j] = std::max(mn[i][k] + mn[k][j],mn[i][j]);
mx[i][j] = std::min(mx[i][k] + mx[k][j],mx[i][j]);
}
}
int c1 = 0,c2 = 0,c3 = 0;
for(int i = 1;i <= n;++ i) {
for(int j = i + 1;j <= n;++ j) {
if(i == j || i == A || i == B || j == A || j == B)continue;
if(mn[A][i] > mx[j][B] || mn[A][j] > mx[i][B]) c1 ++;
if(mn[A][i] == mx[A][i] && mn[j][B] == mx[j][B] && mn[j][B] == mn[A][i]) c2 ++;
else if(mn[A][j] == mx[A][j] && mn[i][B] == mx[i][B] && mn[A][j] == mn[i][B]) c2 ++;
if(mx[A][i] < mn[j][B] || mx[A][j] < mn[i][B]) c3 ++;
}
}
printf("%d %d %d\n",c1,c2,c3);
return 0;
}