站外题:给定一张无向图,保证连通,有N个的结点,每个点有点权,求给定询问x与y,求路径上权最大的点(包括起点和终点)加上路径上所有的边的权值的最小值(n<=300)
蒟蒻的思路:仿照floyd维护这个最小值,具体细节如下,求大佬指导。
现已经指导这是一个假做法,但没有想明白问什么,求指点 Orz
#include <bits/stdc++.h>
#define ll long long
#define N 305
using namespace std;
ll n,m,q;
ll a[N],g[N][N],f[N][N];//f[i][j]表示在两者和最小情况下i->j路径上权值最大点,g[i][j]表示在两者和最小情况下i->j路径最小值
void floyd(){
ll i,j,k;
for (k=1;k<=n;k++){
for (i=1;i<=n;i++){
for (j=1;j<=n;j++){
//cout<<i<<" "<<k<<" "<<j<<endl;
if (i==j) continue;
if (g[i][k]+g[k][j]+max(f[i][k],f[k][j])<g[i][j]+f[i][j]){//更新
g[i][j]=g[i][k]+g[k][j];
f[i][j]=max(f[i][k],f[k][j]);
}
}
}
}
}
int main (){
//freopen("cost.in","r",stdin);
//freopen("cost.out","w",stdout);
ll x,y,z,i,j;
scanf("%lld%lld",&n,&m);
for (i=1;i<=n;i++){
scanf("%lld",&a[i]);
f[i][i]=a[i];
}
memset(g,0x3f,sizeof(g));
memset(ans,0x3f,sizeof(ans));
for (i=1;i<=m;i++){
scanf("%lld%lld%lld",&x,&y,&z);
g[x][y]=g[y][x]=min(g[x][y],z);
f[x][y]=f[y][x]=max(a[x],a[y]);
}
floyd();
scanf("%d",&q);
for (i=1;i<=q;i++){
scanf("%lld%lld",&x,&y);
printf("%lld\n",f[x][y]+g[x][y]);
}
return 0;
}