题目描述
A 国有 N 个城市,编号为 1 . . . N。小明是编号为 1 的城市中一家公司的员工,今天突然接到了上级通知需要去编号为 N 的城市出差。
由于疫情原因,很多直达的交通方式暂时关闭,小明无法乘坐飞机直接从城市 1 到达城市 N,需要通过其他城市进行陆路交通中转。小明通过交通信息网,查询到了 M 条城市之间仍然还开通的路线信息以及每一条路线需要花费的时间。
同样由于疫情原因,小明到达一个城市后需要隔离观察一段时间才能离开该城市前往其他城市。通过网络,小明也查询到了各个城市的隔离信息。(由于小明之前在城市 1,因此可以直接离开城市 1,不需要隔离)
由于上级要求,小明希望能够尽快赶到城市 N,因此他求助于你,希望你能帮他规划一条路线,能够在最短时间内到达城市 N。
输入格式
第 1 行:两个正整数 N, M, N 表示 A 国的城市数量,M 表示未关闭的路线数量
第 2 行:N 个正整数,第 i 个整数 Ci 表示到达编号为 i 的城市后需要隔离的时间
第 3 . . . M + 2 行:每行 3 个正整数,u, v, c,表示有一条城市 u 到城市 v 的双向路线仍然开通着,通过该路线的时间为 c
输出格式
第 1 行:1 个正整数,表示小明从城市 1 出发到达城市 N 的最短时间(到达城市 N,不需要计算城市 N 的隔离时间)
样例输入
4 4
5 7 3 4
1 2 4
1 3 5
2 4 3
3 4 5
样例输出
13
提示
路线 1:1 -> 2 -> 4,时间为 4+7(隔离)+3=14
路线 2:1 -> 3 -> 4,时间为 5+3(隔离)+5=13
对于 100% 的数据,1 ≤ N ≤ 1000 , 1 ≤ M ≤ 10000, 1 ≤ Ci ≤ 200, 1 ≤ u, v ≤ N, 1 ≤ c ≤ 1000
解析:
Dijkstra,每个城市的隔离时间,可以加到以该城市为终点的有向边的交通时间上,最后的结果减掉 n 点的隔离时间。
注意,如果 n 为 1 要特判。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
const int INF=0x3f3f3f3f;
struct edge{
int to,w;
};
struct node{
int id,dis;
bool operator<(const node& a)const{
return dis>a.dis;
}
};
int n,m,num[N];
vector<edge>e[N];
void Dijkstra(){
int s=1,dis[N],done[N];
for(int i=1;i<=n;i++) dis[i]=INF,done[i]=0;
priority_queue<node>q;
s=1,dis[s]=0;
q.push({s,dis[s]});
while(q.size()){
node u=q.top();
q.pop();
if(done[u.id]) continue;
done[u.id]=1;
for(int i=0;i<e[u.id].size();i++){
edge x=e[u.id][i];
if(done[x.to]) continue;
if(dis[x.to]>x.w+u.dis){
dis[x.to]=x.w+u.dis;
q.push({x.to,dis[x.to]});
}
}
}
cout<<dis[n]-num[n];
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&num[i]);
for(int i=0;i<m;i++){
int a,b,w;
scanf("%d%d%d",&a,&b,&w);
e[a].push_back({b,w+num[b]});
e[b].push_back({a,w+num[a]});
}
if(n==1){
cout<<0;
return 0;
}
Dijkstra();
return 0;
}