• 洛谷 P3371【模板】单源最短路径(弱化版)


    题面

    既然是模板, 那就直接贴代码?

    两种思路

    1.迪杰斯特拉

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int N = 500007;
    int head[N], cnt, n, m, s;
    long long dis[N];
    bool vis[N];
    struct node {
        int next, to;
        long long w;
    }e[N];
    void add(int x, int y, long long z) {
        e[++cnt].next = head[x];
        e[cnt].to = y;
        e[cnt].w = z;
        head[x] = cnt;
    } 
    void dijkstra(int s) {
        for(int i = 1; i <= n; i++) dis[i] = 2147483647; 
        dis[s] = 0;
        for(int i = 1; i <= n; i++) {
            int k = 1, maxn = 2147483647;
            for(int j = 1; j <= n; j++)
                if(!vis[j] && dis[j] <= maxn)
                    k = j, maxn = dis[j];
            vis[k] = 1;
            for(int j = head[k]; j; j = e[j].next) 
                if(dis[e[j].to] > dis[k] + e[j].w)
                    dis[e[j].to] = dis[k] + e[j].w;
        }
    }
    int main () {
        scanf("%d%d%d", &n, &m, &s);
        for(int i = 1; i <= m; i++) {
            int x, y;
            long long z;
            scanf("%d%d%lld", &x, &y, &z);
            add(x, y, z);
        }
        dijkstra(s);
        for(int i = 1; i <= n; i++)
            printf("%lld ", dis[i]);
        return 0;
    }

    2.spfa

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #define N 500005
    #define inf 2147483647
    using namespace std;
    int n, m, s, cnt;
    int dis[N], vis[N], head[N];
    struct node {
        int next, to, w;
    }tr[N];
    void add (int x, int y, int z) {
        tr[++cnt].to = y;
        tr[cnt].next = head[x];
        tr[cnt].w = z;
        head[x] = cnt;
    }
    void spfa () {
        queue<int> q;
        for (int i = 1; i <= n; i++) 
            dis[i] = inf;
        vis[s] = 1;
        q.push(s);
        dis[s] = 0;
        while (!q.empty()) {
            int he = q.front();
            q.pop();
            vis[he] = 0;
            for (int i = head[he]; i ;i = tr[i].next) {
                if (dis[tr[i].to] > dis[he] + tr[i].w) {
                    dis[tr[i].to] = dis[he] + tr[i].w;
                    if (!vis[tr[i].to]) {
                        vis[tr[i].to] = 1;
                        q.push(tr[i].to);
                    }
                }
            }
        }
    }
    int main () {
        scanf ("%d%d%d", &n, &m, &s);
        for (int i = 1; i <= m; i++) {
            int a, b, c;
            scanf ("%d%d%d", &a, &b, &c);
            add (a, b, c);
        }
        spfa ();
        for (int i = 1; i <= n; i++) 
            if (s == i) printf ("0 ");
            else printf ("%d ", dis[i]);
        return 0;
    }

     add:2019.8.15

    增加堆优化后的迪杰斯特拉算法;

    用来切标准版

    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    const int N = 1010001;
    int n, m, s, cnt, head[N], dis[N];
    bool vis[N];
    struct node{
        int next, to, w;
    }e[N];
    int read() {
        int s = 0, w = 1;
        char ch = getchar();
        while(!isdigit(ch)){if(ch == '-') w = -1;ch = getchar();}
        while(isdigit(ch)){s = s * 10 + ch - '0';ch = getchar();}
        return s * w;
    }
    void add(int x, int y, int z) {
        e[++cnt].next = head[x];
        e[cnt].to = y;
        e[cnt].w = z;
        head[x] = cnt;
    }
    struct Node {
        int u, v;
        bool operator<(const Node &b) const {
            return u > b.u;
        }
    };
    void dijikstra(int s) {
        priority_queue <Node> q;
        memset(dis, 0x3f3f3f3f, sizeof(dis));
        dis[s] = 0;
        Node o;
        o.u = 0;
        o.v = s;
        q.push(o);
        while(!q.empty()) {
            int u = q.top().v;
            int d = q.top().u;
            q.pop();
            if(d != dis[u])continue;
            for(int i = head[u]; i; i = e[i].next) {
                int v = e[i].to;
                int w = e[i].w;
                if(dis[v] > dis[u] + w) {
                    dis[v] = dis[u] + w;
                    Node p;
                    p.u = dis[v], p.v = v;
                    q.push(p);
                }
            }
        }
    }
    int main () {
        n = read();
        m = read();
        s = read();
        while(m--) {
            int x, y, z;
            x = read();
            y = read();
            z = read();
            add (x, y, z);
        }
        dijikstra(s);
        for(int i = 1; i <= n; i++)
            printf("%d ", dis[i]);
        return 0; 
    }
  • 相关阅读:
    CodeForces Gym 100935G Board Game DFS
    CodeForces 493D Vasya and Chess 简单博弈
    CodeForces Gym 100935D Enormous Carpet 快速幂取模
    CodeForces Gym 100935E Pairs
    CodeForces Gym 100935C OCR (水
    CodeForces Gym 100935B Weird Cryptography
    HDU-敌兵布阵
    HDU-Minimum Inversion Number(最小逆序数)
    七月馒头
    非常可乐
  • 原文地址:https://www.cnblogs.com/yanxiujie/p/11203575.html
Copyright © 2020-2023  润新知