【模板】【洛谷P4779】 单源最短路径 (优先队列 堆优化)

这里先不放题 我们来说说这个模板需要用到哪些知识点

1.优先队列 (priority_queue)(用于优化) //这个百度一下就明白了

2.运算符重载 (洛谷好像不支持友元函数重载,会编译错误) (更改优先队列排序顺序) //同上 百度

3.BFS(思维核心) https://www.bilibili.com/video/av25829980  这个视频讲的很好,后半段的代码就不用看了 自己敲

4.链式前向星(用来存图) //https://blog.csdn.net/acdreamers/article/details/16902023 带你深入了解为何这样建图

一发A掉还是很开心的,自己其实也没想到 .


题目背景

2018 年 7 月 19 日,某位同学在 NOI Day 1 T1 归程 一题里非常熟练地使用了一个广为人知的算法求最短路。

然后呢?

100→60100 \rightarrow 60100→60 ;

Ag→CuAg \rightarrow CuAg→Cu ;

最终,他因此没能与理想的大学达成契约。

小 F 衷心祝愿大家不再重蹈覆辙。

题目描述

给定一个 NNN 个点, MMM 条有向边的带非负权图,请你计算从 SSS 出发,到每个点的距离。

数据保证你能从 SSS 出发到任意点。

输入输出格式

输入格式:

第一行为三个正整数 N,M,SN, M, SN,M,S 。 第二行起 MMM 行,每行三个非负整数 ui,vi,wiu_i, v_i, w_iui​,vi​,wi​ ,表示从 uiu_iui​ 到 viv_ivi​ 有一条权值为 wiw_iwi​ 的边。

输出格式:

输出一行 NNN 个空格分隔的非负整数,表示 SSS 到每个点的距离。

输入输出样例

输入样例#1: 复制

4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4

输出样例#1: 复制

0 2 4 3

说明

样例解释请参考 数据随机的模板题

1≤N≤1000001 \leq N \leq 1000001≤N≤100000 ;

1≤M≤2000001 \leq M \leq 2000001≤M≤200000 ;

S=1S = 1S=1 ;

1≤ui,vi≤N1 \leq u_i, v_i\leq N1≤ui​,vi​≤N ;

0≤wi≤1090 \leq w_i \leq 10 ^ 90≤wi​≤109 ,

0≤∑wi≤1090 \leq \sum w_i \leq 10 ^ 90≤∑wi​≤109 。

本题数据可能会持续更新,但不会重测,望周知。


#include<bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
#define maxn 500005
#define mod 1e9+7
#define inf 2147483647
typedef long long ll;
ll n,m,s,ans[maxn],head[maxn],num,flag[maxn]; 
struct Why
{
    ll next,now,dis;
}plat[maxn]; //结构体表示静态邻接表
struct Whhy  
{
    ll now,dis;
    Whhy(ll x,ll y)
    {
        now = x;
        dis = y;
    }
    bool operator < (const Whhy t) const //重载
    {
        return dis > t.dis;
    }
};
void build(ll a,ll b,ll c) //链式前向星建图
{
    plat[++num].next = head[a]; //链式存储下一条边
    plat[num].now = b; //记录可以到达的当前节点编号
    plat[num].dis = c; //记录到当前节点编号的距离
    head[a] = num; //记录下一次出边情况
    return ;
}
void bfs(ll x)
{
    priority_queue<Whhy>A;
    A.push( Whhy(x,0) );
    while(!A.empty())
    {
        Whhy temp = A.top();
        A.pop();
        if( flag[temp.now] == 0 )
        {
            flag[ temp.now ] = 1;
            if( temp.dis < ans[ temp.now  ]  )  //更新ans数组 
                ans[ temp.now ] = temp.dis;
            for(ll i = head[temp.now]; i != 0; i = plat[i].next )
            {
                A.push( Whhy( plat[i].now, temp.dis+plat[i].dis) );
            }
        }
    }
    return ;
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> n >> m >> s;
    for(ll i = 1; i <= m; i++)
    {
        ll a,b,c;
        cin >> a >> b >> c;
        build(a,b,c);
    }
    for(ll i = 1; i <= n; i++) 
        ans[i] = inf;
    bfs(s);
    for(ll i = 1; i <= n; i++)
        cout << ans[i] << " ";
    cout << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Whyckck/article/details/81672587
今日推荐