zoukankan      html  css  js  c++  java
  • 洛谷 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; 
    }
  • 相关阅读:
    Qt 获取文件夹下所有文件
    [MAC OS] 解压Assets.car获取资源图片
    [Mac OS] Homebrew简介及安装wine
    [Android Pro] Android7.0系统 关于Android获取流量计数TrafficStats.getUidRxBytes(uid)和TrafficStats.getUidTxBytes(uid)返回-1解决方案
    [Android Pro] git 打标签、推送tag到托管服务器、验证是否成功
    [Android Pro] 分析 Package manager has died
    [Android Pro] Android 必知必会-使用 supportV4 的 RoundedBitmapDrawable 实现圆角
    [Linux] du-查看文件夹大小-并按大小进行排序
    [Android Pro] Android异步任务处理之AsyncTaskLoader的使用
    [Android] charles高级使用总结
  • 原文地址:https://www.cnblogs.com/yanxiujie/p/11203575.html
Copyright © 2011-2022 走看看