bzoj1077: [SCOI2008]天平

题目链接

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

posted @ 2018-07-12 08:23  zzzzx  阅读(266)  评论(0编辑  收藏  举报