P8802 [蓝桥杯 2022 国 B] 出差

65 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 5 天,点击查看活动详情

[蓝桥杯 2022 国 B] 出差

题目描述

A\mathrm{A} 国有 NN 个城市,编号为 1N1 \ldots N 小明是编号为 11 的城市中一家公司的员工,今天突然接到了上级通知需要去编号为 NN 的城市出差。

由于疫情原因,很多直达的交通方式暂时关闭,小明无法乘坐飞机直接从城市 11 到达城市 NN,需要通过其他城市进行陆路交通中转。小明通过交通信息网,查询到了 MM 条城市之间仍然还开通的路线信息以及每一条路线需要花费的时间。

同样由于疫情原因,小明到达一个城市后需要隔离观察一段时间才能离开该城市前往其他城市。通过网络,小明也查询到了各个城市的隔离信息。(由于小明之前在城市 11,因此可以直接离开城市 11,不需要隔离)

由于上级要求,小明希望能够尽快赶到城市 N\mathrm{N}, 因此他求助于你,希望你能帮他规划一条路线,能够在最短时间内到达城市 NN

输入格式

11 行:两个正整数 N,MN, M 表示 A 国的城市数量, MM 表示末关闭的路线数量。

22 行: NN 个正整数,第 ii 个整数 CiC_{i} 表示到达编号为 i\mathrm{i} 的城市后需要隔离的时间。

3M+23 \ldots M+2 行: 每行 33 个正整数, u,v,cu, v, c, 表示有一条城市 uu 到城市 vv 的双向路线仍然开通着,通过该路线的时间为 cc

输出格式

11 行:11 个正整数,表示小明从城市 11 出发到达城市 NN 的最短时间。(到达城市 NN,不需要计算城市 NN 的隔离时间)

样例 #1

样例输入 #1

4 4
5 7 3 4
1 2 4
1 3 5
2 4 3
3 4 5

样例输出 #1

13

提示

【样例说明】

【评测用例规模与约定】

对于 100%100 \% 的数据, 1N1000,1M10000,1Ci200,1u,v1 \leq N \leq 1000,1 \leq M \leq 10000,1 \leq C_{i} \leq 200,1 \leq u, v \leq N,1c1000N, 1 \leq c \leq 1000

蓝桥杯 2022 国赛 B 组 E 题。

分析

这题其实是一个比较显然的题目,就是最短路,用一下dijkstra,要注意的是第一边权是stay[指向点]+w,然后一定要注意的就是最后要减去stay[n],因为只要到了就行了,不需要再等待了。

代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <map>
#include <set>
#include <iomanip>
#include <cmath>
#include <unordered_map>
#include <stack>
#include <queue>
#define ll long long
#define lowbit(x) x&(-x)
using namespace std;
typedef pair<int,int> PII;
typedef pair<string,int> PSI;
int gcd(int x,int y){
    return y?gcd(y,x%y):x;
}
ll qmi(ll x,ll y,int mod){
    ll res=1;
    while(y){
        if(y&1) res=res*x%mod;
        y>>=1;
        x=x*x%mod;
    }
    return res;
}
const int N=200100;
int idx,n,m,e[N],ne[N],h[N],stay[N],w[N];
ll dist[N];
bool st[N];
inline void add(int a,int b,int c){
    e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
inline void dijkstra(){
    priority_queue<PII,vector<PII>,greater<PII>> heap;
    memset(st,0,sizeof st);
    memset(dist,0x3f,sizeof dist);
    dist[1]=0;
    heap.push({0,1});
    while(heap.size()){
        PII t=heap.top();
        heap.pop();
        int ver=t.second,distance=t.first;
        if(st[ver]) continue;
        st[ver]=true;
        for(int i=h[ver];~i;i=ne[i]){
            int j=e[i];
            if(dist[j]>distance+w[i]){
                dist[j]=distance+w[i];
                heap.push({dist[j],j});
            }
        }
    }
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    memset(h,-1,sizeof h);
    for(int i=1;i<=n;i++) cin>>stay[i];
    while(m--){
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c+stay[b]);
        add(b,a,c+stay[a]);
    }
    dijkstra();
    cout<<dist[n]-stay[n]<<"\n";
    return 0;
}

qaq希望能帮助到大家!