题面
题面分析
一看就知道是一个裸的最短路啊。
看见题目数据那么小,果断选择
f
l
o
y
d
floyd
floyd。
这里要注意两个细节:
-
f
[
x
]
[
y
]
=
f
[
y
]
[
x
]
=
m
i
n
(
f
[
x
]
[
y
]
,
w
)
;
f[x][y]=f[y][x]=min(f[x][y],w);
f[x][y]=f[y][x]=min(f[x][y],w);
这里要注意去重。 -
f
o
r
(
i
=
0
;
i
<
n
;
i
+
+
)
for(i=0;i<n;i++)
for(i=0;i<n;i++)
f [ i ] [ i ] = 0 ; f[i][i]=0; f[i][i]=0;
这里是防止自环
(这两个地方卡了我好久)
代码
#include <bits/stdc++.h>
using namespace std;
int a[1039],f[1039][1039],n,m,q;
inline void Floyd(int k){
register int i,j;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(f[i][j]>f[i][k]+f[k][j])
f[i][j]=f[i][k]+f[k][j];
}
int main(){
memset(f,0x3f,sizeof(f));
register int i,x,y,w,tot=0;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
scanf("%d",a+i);
for(i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&w);
f[x][y]=f[y][x]=min(f[x][y],w);
}
for(i=0;i<n;i++)
f[i][i]=0;
scanf("%d",&q);
while(q--){
scanf("%d%d%d",&x,&y,&w);
while(a[tot]<=w&&tot<n) Floyd(tot),++tot;
if(a[x]>w||a[y]>w||f[x][y]>5e8) puts("-1");
else printf("%d\n",f[x][y]);
}
return 0;
}