题目描述
旅行是一件颇有趣的事情,但是在旅行前规划好路线也很重要。

现在小D计划要去U国旅行。

U国有N个城市,M条道路,每条道路都连接着两个城市,并且经过这条道路需要一定的费用wi。

现在小D想要从u城市到v城市,但是他的汽车需要在途中加一次油(途中包括u和v两个城市)。在每个城市加油都有不同的费用vi。

小D想知道从u城市到v城市最少需要多少费用(经过道路的费用+加油的费用)。

城市从1-n进行编号。

格式
输入格式
第一行两个正整数n,m,表示n个城市,m条无向道路
接下来n行,第i行一个整数vi,表示第i个城市的加油费用
接下来m行,第i行三个整数ai, bi, wi,表示第i条道路连接ai和bi两个城市,经过要花费wi的费用
接下来一个正整数q,表示小D有q个询问
接下来q行,第i行两个整数ui, vi, 表示小D想知道从ui到vi需要的最少费用(ui和vi可能相等)

输出格式
对于每个询问,输出一行整数,表示最小的费用,如果ui不能到达vi,则输出-1

样例1
样例输入1
3 6
2666
3977
2457
1 2 6920
1 2 276
1 3 839
3 1 3490
2 1 7395
3 1 7540
6
3 2
3 1
2 2
2 1
3 2
2 2
样例输出1
3572
3296
3218
2942
3572
3218
限制
每个测试点1s

提示
对于30%的数据,保证n<=10
对于70%的数据,保证n<=80
对于100%的数据,保证n<=300
保证q,m<=n*n, 0 <= wi, vi <= 10000
数据中可能有重边和自环

一个最短路的水题。

先跑一边floyd求出每个点之间的最短路径,然后再枚举每一个点作为加油站时的最小花费就行了 。

#include<bits/stdc++.h>
using namespace std;
const int inf=1e8;
const int N=310;
int n,m,q,g[N][N],f[N][N],w[N];
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++)	g[i][j]=f[i][j]=inf;
	for(int i=1;i<=n;i++)	cin>>w[i],g[i][i]=0;
	while(m--)
	{
		int a,b,w;
		cin>>a>>b>>w;
		g[a][b]=g[b][a]=min(g[a][b],w);
	}
	for(int k=1;k<=n;k++)//floyd
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				f[i][j]=min(f[i][j],w[k]+g[i][k]+g[k][j]);//当k点为加油站时
	cin>>q;
	while(q--)
	{
		int a,b;
		cin>>a>>b;
		cout<<f[a][b]<<endl;
	}
	return 0;
}