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


         洛谷 P4779【模板】单源最短路径(标准版)

    题目背景

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

    然后呢?

    10060 ;

     AgCu ;

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

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

    题目描述

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

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

    输入输出格式

    输入格式:

    第一行为三个正整数 N, M, S。 第二行起 M 行,每行三个非负整数 ui,vi,wi ,表示从 ui 到 vi 有一条权值为 wi 的边。

    输出格式:

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

    输入输出样例

    输入样例#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

    说明

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

    ≤ ≤ 100000 ;

    ≤ ≤ 200000 ;

    S = 1 ;

    ≤ ui,v≤ N ;

    ≤ wi​ ≤ 109,

    ≤ w≤ 109 。

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

    思路:spfa+优先队列优化  or  dijkstra+堆优化

     用P3371中的代码(再开上long long),可以过掉后两个点,但前几个点都会TLE

    #include<iostream>
    #include<cstring>
    #include<cctype>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #define M 100005
    using namespace std;
    int n, m, s, a, b, c;
    struct Edge {
        int to, dis;
    };
    vector<Edge> G[M];
    inline int read() {
        int X = 0, z = 0; char ch = 0;
        while(!isdigit(ch)) z = ch == '-' ? 1 : 0, ch = getchar();
        while(isdigit(ch)) X = (X<<1) + (X<<3) + (ch^48), ch = getchar();
        return z ? -X : X;
    }
    long long dis[M];
    bool inqueue[M];
    struct Node {
        int x;
    };
    bool operator < (const Node &x, const Node &y) {
        return dis[x.x] > dis[y.x];
    }
    priority_queue<Node> Q;
    int cnt;
    bool hasout[M];
    inline bool SPFA(int S) {
        memset(dis, 0x3f, sizeof dis);
        memset(inqueue, 0, sizeof inqueue);
        Q.push((Node) {
            S
        });
        inqueue[S] = 1; dis[S] = 0;
        int u, v, cost;
        while(!Q.empty()) {
            u = Q.top().x; Q.pop();
            if(!hasout[u]) cnt++;
            if(cnt == n) return 1;
            hasout[u] = 1;
            inqueue[u] = false;
            for(int i = 0; i < G[u].size(); ++i) {
                v = G[u][i].to;
                cost = G[u][i].dis;
                if(dis[v] > dis[u] + cost) {
                    dis[v] = dis[u] + cost;
                    if(!inqueue[v]) {
                        inqueue[v] = true;
                        Q.push((Node) {
                            v
                        });
                    }
                }
            }
        }
        return 1;
    }
    int main() {
        n = read(); m = read(); s = read();
        for(register int i = 1; i <= m; ++i) {
            a = read(), b = read(), c = read();
            G[a].push_back((Edge) {
                b, c
            });
        }
        SPFA(s);
        for(register int i = 1; i <= n; ++i)
            printf("%d ", dis[i]);
            return 0;
    }
    spfa+优先队列
  • 相关阅读:
    Programming Contest Ranking(题解)
    Alphabet Cookies
    hpu 1267 Cafeteria (01背包)
    Triangles 正多边形分割锐角三角形
    ACdream 1067:Triangles
    hdu 1253 胜利大逃亡 (代码详解)解题报告
    最短路
    POJ- 1511 Invitation Cards
    E
    HDU
  • 原文地址:https://www.cnblogs.com/v-vip/p/9409889.html
Copyright © 2020-2023  润新知