• 【模板】单源最短路径(标准版)


    题目背景

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

    然后呢?

    100 ightarrow 6010060;

    Ag ightarrow CuAgCu;

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

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

    题目描述

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

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

    输入格式

    第一行为三个正整数 N, M, SN,M,S。 第二行起 MM 行,每行三个非负整数 u_i, v_i, w_iui,vi,wi,表示从 u_iui 到 v_ivi有一条权值为 w_iwi 的边。

    输出格式

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

    输入输出样例

    输入 #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 leq N leq 1000001N100000;

    1 leq M leq 2000001M200000;

    S = 1S=1;

    1 leq u_i, v_ileq N1ui,viN;

    0 leq w_i leq 10 ^ 90wi109,

    0 leq sum w_i leq 10 ^ 90wi109。

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

    2018.09.04 数据更新 from @zzq

    使用了堆优化的Dijkstra。

    时间复杂度为O(m log n)O(m log n)。

    if (dis[u]!=d) continue

    每次松弛操作后,要删除堆中原有的节点,这样很不方便,所以就加上这一句话判断是否被删除过。

    小二,上代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N=100010,M=200020;
    int tot=0;
    int n,m,s;
    int head[N];
    long long d[N];
    bool v[N];
    priority_queue<pair<long long,int> > q;
    
    inline int read1(){
        int ret=0,f=1;char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
        while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
        return ret*f;
    }
    
    inline long long read2(){
        long long ret=0,f=1;char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-f;ch=getchar();}
        while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
        return ret*f;
    }
    
    struct edge{
        int ver,next;
        long long len;
    }e[M];
    
    void add(int x,int y,long long z){
        e[++tot].ver=y;
        e[tot].len=z;
        e[tot].next=head[x];
        head[x]=tot;
    }
    
    void dijkstra(){
        memset(v,0,sizeof(v));
        for(register int i=1;i<=n;i++){
            d[i]=2147483647;
        }
        d[s]=0;
        q.push(make_pair(0,1));
        while(!q.empty()){
            int x=q.top().second;
            q.pop();
            if(v[x])
                continue;
            for(register int i=head[x];i;i=e[i].next){
                int y=e[i].ver,z=e[i].len;
                if(d[y]>d[x]+z){
                    d[y]=d[x]+z;
                    q.push(make_pair(-d[y],y));
                    v[x]=1;
                }
            }
        }
    }
    
    int main(){
        scanf("%d%d%d",&n,&m,&s);
        for(register int i=1;i<=m;i++){
            int x,y;
            long long z;
            x=read1();
            y=read1();
            z=read2();
            add(x,y,z);
        }
        dijkstra();
        for(register int i=1;i<=n;i++){
            printf("%lld ",d[i]);
        }
        printf("
    ");
        return 0;
    }
  • 相关阅读:
    hdu 3790 最短路径问题
    hdu 2112 HDU Today
    最短路问题 以hdu1874为例
    hdu 1690 Bus System Floyd
    hdu 2066 一个人的旅行
    hdu 2680 Choose the best route
    hdu 1596 find the safest road
    hdu 1869 六度分离
    hdu 3339 In Action
    序列化和反序列化
  • 原文地址:https://www.cnblogs.com/hrj1/p/11160991.html
Copyright © 2020-2023  润新知