#include <bits/stdc++.h>
using namespace std;
const long long N=305, M=5e12; 
int n, m, i, j, k, x, y, a[N];
long long f[N][N], p, q;
char s[N];
int main(){
    scanf("%d", &n);
    for(i=1; i<=n; i++) scanf("%d", &a[i]);
    memset(f, -2, sizeof(f));//求最大值,默认无穷小
    for(i=1; i<=n; i++){
        scanf("%s", s+1);
        for(j=1; j<=n; j++){
            if(s[j] == 'Y'){
                f[i][j] = -M + a[i] + a[j];
            }//有边,边权为点权和
        }//因为尽量少边,每条边扣除M费用
    }
    for(k=1; k<=n; k++){
        for(i=1; i<=n; i++){
            for(j=1; j<=n; j++){
                f[i][j] = max(f[i][j], f[i][k]+f[k][j]-a[k]);
            }
        }
    }//弗洛伊德求最长路,点权和不超过M,保证边最少 
    scanf("%d", &m);
    while(m--){
        scanf("%d%d", &x, &y);
        if(f[x][y] == f[0][0]) printf("Impossible\n");
        else{
            q = f[x][y] % M + M;//负数转正 
            p = (f[x][y]-q) / M;//向上取整 
            printf("%lld %lld\n", -p, q);
        }//分解出边数和点权和 
    }
    return 0;
}

作者 crxis

发表回复