最短路算法

https://hihocoder.com/problemset/problem/1093
实现参考了算法导论。

#include <bits/stdc++.h>
#define DBG(x) cerr << #x << " = " << x << endl

using namespace std;
typedef long long LL;

const int MAX_N = 100000 + 16;
const int MAX_M = 1000000 + 16;
const int INF = 0x3F3F3F3F;

struct Edge {
    int u, v, c;

    Edge() {}

    Edge(int u, int v, int c) : u(u), v(v), c(c) {}
};

struct Graph {
    vector<int> g[MAX_N];
    vector<Edge> edges;
    int n;

    void init(int n) {
        this->n = n;
        for (int i = 0; i <= n; i++)
            g[i].clear();
        edges.clear();
    }

    void add(int u, int v, int c) {
        edges.push_back(Edge(u, v, c));
        g[u].push_back(edges.size() - 1);
    }
} graph;

struct BellmanFord {
    int dist[MAX_N];

    void init(int n, int s) {
        for (int i = 0; i <= n; i++)
            dist[i] = INF;
        dist[s] = 0;
    }

    void work(const Graph &g, int s) {
        init(g.n, s);
        for (int i = 1; i < g.n; i++) {
            for (const Edge &e : g.edges) {
                dist[e.v] = min(dist[e.v], dist[e.u] + e.c);
            }
        }
    }
} bellman_ford;

struct Dijkstra {
    int dist[MAX_N];
    bool vis[MAX_N];

    void init(int n, int s) {
        for (int i = 0; i <= n; i++) {
            dist[i] = INF;
            vis[i] = false;
        }
        dist[s] = 0;
    }

    int extract_min(int n) {
        int d = INF;
        int u = 0;
        for (int i = 1; i <= n; i++) {
            if (!vis[i] && dist[i] < d) {
                d = dist[i];
                u = i;
            }
        }
        return u;
    }

    void work(const Graph &g, int s) {
        init(g.n, s);
        int left = g.n;
        while (left--) {
            int u = extract_min(g.n);
            vis[u] = true;
            for (int i = 0; i < g.g[u].size(); i++) {
                const Edge &e = g.edges[g.g[u][i]];
                dist[e.v] = min(dist[e.v], dist[e.u] + e.c);
            }
        }
    }
} dijkstra;

struct DijkstraPremium {
    struct Node {
        int u, d;

        Node() {}

        Node(int u, int d) : u(u), d(d) {}

        bool operator>(const Node &rhs) const {
            return this->d > rhs.d;
        }
    };

    int dist[MAX_N];
    bool vis[MAX_N];
    priority_queue<Node, vector<Node>, greater<Node>> pq;

    void init(int n, int s) {
        for (int i = 0; i <= n; i++) {
            dist[i] = INF;
            vis[i] = false;
        }
        dist[s] = 0;
        while (!pq.empty())
            pq.pop();
        pq.push(Node(s, dist[s]));
    }

    void work(const Graph &g, int s) {
        init(g.n, s);
        while (!pq.empty()) {
            Node node = pq.top();
            pq.pop();
            int u = node.u;
            if (vis[u])
                continue;

            vis[u] = true;
            for (int i = 0; i < g.g[u].size(); i++) {
                const Edge &e = g.edges[g.g[u][i]];
                dist[e.v] = min(dist[e.v], dist[e.u] + e.c);
                pq.push(Node(e.v, dist[e.v]));
            }
        }
    }
} dijkstra_premium;

int main(int argc, char **argv) {
    int n, m, s, t;
    while (scanf("%d%d%d%d", &n, &m, &s, &t) != EOF) {
        graph.init(n);
        for (int i = 0; i < m; i++) {
            int u, v, c;
            scanf("%d%d%d", &u, &v, &c);
            graph.add(u, v, c);
            graph.add(v, u, c);
        }
        dijkstra_premium.work(graph, s);
        printf("%d\n", dijkstra_premium.dist[t]);
    }
    return 0;
}
posted @ 2019-11-05 18:35  ToRapture  阅读(127)  评论(0编辑  收藏  举报