answer
An in-depth understanding of the nature of the subject Floyd
Floyd essence of: obtaining from the i-th vertex to vertex number j via the shortest path just before the k number of vertices
in this question, the order of time (because t is not reduced) updated every a point available for the most short-circuited,
corresponds exactly thinking Floyd algorithm: calculated vertex to vertex x k y front within the shortest time
big brother blog, really great, must see
#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;//不可以使用1e9 爆范围了
const int N=1e3+10;
int t[N],f[N][N];//重建时间 两点之间的距离
int n,m,u,v,c;
void update(int k){
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
//if(i==j||i==k||k==j)continue;
/*
if(f[i][k]!=INF && f[k][j]!=INF && t[i]<=k && t[j]<=k) 这个写法是错的
假如B的重建时间晚于A 那么在用A更新各个点的时候就会跳过B
当用B更新各个点的时候就无法得知AB之间的距离 从而出现差错
所以写Floyd时 这一段是不可以更改的
*/
if(f[i][k]!=INF && f[k][j]!=INF)
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
}
}
int main()
{
memset(f, INF, sizeof f);
cin>>n>>m;
for (int i = 0 ; i < n; i++) {
f[i][i]=0;
cin>>t[i];
}
for (int i = 1; i <= m; i++) {
cin>>u>>v>>c;
f[u][v]=f[v][u]=c;
}
int que;
int now=0;//村庄的编号
cin>>que;
for (int i = 1; i <= que; i++) {
cin>>u>>v>>c;
while(now<n && t[now]<=c){//找到已经重建号的前k个村庄 题目说了 村庄修建时间是从小到大的
update(now);
++now;
}
if(f[u][v]!=INF && t[u]<=c && t[v]<=c) printf("%d\n", f[u][v]);
else puts("-1");
}
return 0;
}