[ABC286E] Souvenir - 洛谷
#include <bits/stdc++.h>
#define int long long //(有超时风险)
#define PII pair<int,int>
#define endl '\n'
#define LL __int128
using namespace std;
const int N=2e5+10,M=1e3+10,mod=998244353,INF=0x3f3f3f3f;
int a[M];
char g[M][M];
int d[M][M],w[M][M];
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int n;cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
//本题思路:floyd+维护点权的值。
//每个点上面有点权值,那么边的值就是两个点的点权值相加。
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
char ch;cin>>ch;
if(i==j)
{
w[i][j]=a[i];
d[i][j]=0;
}
else
{
if(ch=='Y')
{
d[i][j]=1;
w[i][j]=a[i]+a[j];
}
else
{
d[i][j]=INF;
w[i][j]=0;
}
}
}
}
//floyd过程中维护w的值。
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(d[i][j]>d[i][k]+d[k][j])
{
d[i][j]=d[i][k]+d[k][j];
w[i][j]=w[i][k]+w[k][j]-a[k];
}
else if(d[i][j]==d[i][k]+d[k][j])
{
w[i][j]=max(w[i][j],w[i][k]+w[k][j]-a[k]);
}
}
int q;cin>>q;
while(q--)
{
int x,y;cin>>x>>y;
if(d[x][y]>INF/2)
cout<<"Impossible"<<endl;
else
cout<<d[x][y]<<' '<<w[x][y]<<endl;
}
return 0;
}