考虑floyed的过程 每次增加一个中间点k
那么我们按权值从小到大加k 然后每次增量后更新答案
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
typedef pair<int,int> abcd;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int N=305;
int n,m;
int dis[N][N],val[N];
int Q,s[100005],t[100005],ans[100005];
abcd a[N];
int main(){
int iu,iv,iw;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(n); read(m);
read(Q);
for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) dis[i][j]=1<<29;
for (int i=1;i<=n;i++) dis[i][i]=0,read(val[i]),a[i]=abcd(val[i],i);
for (int i=1;i<=m;i++)
read(iu),read(iv),read(iw),dis[iu][iv]=min(dis[iu][iv],iw),dis[iv][iu]=min(dis[iv][iu],iw);
for (int i=1;i<=Q;i++)
read(s[i]),read(t[i]);
sort(a+1,a+n+1);
memset(ans,0x3f,sizeof(ans));
for (int o=1;o<=n;o++){
int k=a[o].second;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
for (int i=1;i<=Q;i++)
ans[i]=min(ans[i],dis[s[i]][t[i]]+max(max(val[s[i]],val[t[i]]),a[o].first));
}
for (int i=1;i<=Q;i++)
printf("%d\n",ans[i]);
return 0;
}