蓝桥杯每日一题13

78 阅读3分钟

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

今天的每日一题快进到我最爱的dijkstra。

有 N� 个村庄,编号 11 到 N�。

村庄之间有 M� 条无向道路,第 i� 条道路连接村庄 ai�� 和村庄 bi��,长度是 ci��。

所有村庄都是连通的。

共有 K� 个村庄有商店,第 j� 个有商店的村庄编号是 xj��。

然后给出 Q� 个询问,第 k� 个询问给出一个村庄的编号 yk��,问该村庄距离最近的商店有多远?

输入格式

第一行包含两个整数 N,M�,�。

接下来 M� 行,每行包含三个整数 ai,bi,ci��,��,��,表示第 i� 条道路连接村庄 ai�� 和村庄 bi��,长度是 ci��。

再一行包含整数 K�。

接下来 K� 行,每行包含一个整数 xj��,表示第 j� 个有商店的村庄编号是 xj��。

再一行包含整数 Q�。

接下来 Q� 行,每行包含一个整数 yk��,表示询问编号为 yk�� 的村庄与其距离最近的商店之间的距离。

输出格式

对于每个询问,输出该询问的结果。

数据范围

2≤N≤1052≤�≤105,
N−1≤M≤min(N(N−1)2,105)�−1≤�≤���(�(�−1)2,105),
1≤Q≤1051≤�≤105,
1≤K≤N1≤�≤�,
1≤ci≤100001≤��≤10000

输入样例:

7 7
1 2 5
1 4 3
2 3 2
2 5 1
3 6 7
5 6 8
6 7 6
3
7
5
4
7
1
2
3
4
5
6
7

输出样例:

3
1
3
0
0
6
0
难度:简单
时/空限制:1s / 64MB
总通过数:1095
总尝试数:2367
来源:Indeed笔试题
算法标签

分析

这道题唯一和板子不一样的地方就是要提前把所有有商店的村庄都放进优先队列,然后跑一遍堆优化的dijkstra就结束了,出奇的简单。

代码

#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;
typedef stack<int> stk;
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=400100;
int dist[N];
bool st[N];
int idx=0,e[N],ne[N],h[N],w[N],n,m,k,q;
inline void add(int a,int b,int c){
    e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
priority_queue<PII,vector<PII>,greater<PII>> heap;
inline void dijkstra(){
    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);
    memset(h,-1,sizeof h);
    cin>>n>>m;
    while(m--){
        int a,b,c;
        cin>>a>>b>>c;
        add(a,b,c),add(b,a,c);
    }
    memset(st,false,sizeof st);
    memset(dist,0x3f,sizeof dist);
    cin>>k;
    while(k--){
        int id;
        cin>>id;
        dist[id]=0;
        heap.push({0,id});
    }
    dijkstra();
    cin>>q;
    while(q--){
        int id;
        cin>>id;
        cout<<dist[id]<<"\n";
    }
    return 0;
}