按照t将点排序,逐一加入图中。
当加入x时,以x为源点跑一次dijkstra,然后以x为跳板跑Floyd的一部分。这样复杂度O(n^2)。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
#define rep(i,j,k) for(i=j;i<=k;++i)
#define per(i,j,k) for(i=j;i>=k;--i)
#define sqr(x) ((x)*(x))
#define G getchar()
#define LL long long
#define pll pair<LL,LL>
#define mkp make_pair
#define X first
#define Y second
#define N 201
#define NN 10000000
#define inf 1061109567
#define eps 0.00001
int n,m,a[N],w[N][N],sa[N],d[N][N],now;bool vis[N],use[N];
int read(){
int x=0;char ch=G;
while(ch<48||ch>57)ch=G;
for(;ch>47&&ch<58;ch=G)x=x*10+ch-48;
return x;
}
bool cmp(int x,int y){
return a[x]<a[y];
}
void dijkstra(int x){
int *D=d[x],i,j,y,tmp;
D[x]=0;
memset(use,0,sizeof use);
rep(i,1,now){
y=0;
rep(j,1,n)if(vis[j]&&!use[j])
if(D[y]>(D[j]=min(D[j],D[x]+w[x][j])))y=j;
use[x=y]=1;
}
}
void Floyd(int k){
int i,j;vis[k]=1;
rep(i,1,n)if(vis[i])rep(j,1,n)if(vis[j])d[i][j]=min(d[i][j],d[k][i]+d[k][j]);
}
int main(){
int i,x,y,z,Q;
n=read();m=read();
rep(i,1,n)a[i]=read();
memset(w,63,sizeof w);
rep(i,1,n)w[i][i]=0;
while(m--){
x=read()+1;y=read()+1;z=read();
w[x][y]=w[y][x]=z;
}
rep(i,1,n)sa[i]=i;
sort(sa+1,sa+n+1,cmp);
memset(d,63,sizeof d);
Q=read();now=1;
while(Q--){
x=read()+1;y=read()+1;z=read();
for(;now<=n&&a[sa[now]]<=z;++now){
dijkstra(sa[now]);
Floyd(sa[now]);
}
printf("%d\n",d[x][y]<inf?d[x][y]:-1);
}
return 0;
}