当前位置:网站首页>洛谷 P1629 邮递员送信 (三种最短路)

洛谷 P1629 邮递员送信 (三种最短路)

2022-08-10 19:07:00 eyuhaobanga

邮递员送信 - 洛谷

题意容易理解,从1出发到其他所有点并返回的最短路,需要先正着跑一边,然后建反边再跑一边

Dijkstra:

#include <bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<n;i++)
using namespace std;
using LL = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    vector<vector<pair<int, int>>> G(n + 1), G1(n + 1);
    vector<int> dist(n + 1, 0x3f3f3f3f), dist1(n + 1, 0x3f3f3f3f);
    rep (i, 0, m) {
        int u, v, c;
        cin >> u >> v >> c;
        G[u].push_back(make_pair(v, c));
        G1[v].push_back(make_pair(u, c));
    }
    LL ans = 0;
    dist[1] = 0;
    set<pair<int, int>> se, se1;
    for (int i = 1; i <= n; i++) {
        se.insert(make_pair(dist[i], i));
    }
    while (!se.empty()) {
        int u = se.begin()->second;
        se.erase(se.begin());
        if (dist[u] > 1 << 30) {
            break;
        }
        for (auto v : G[u]) {
            if (dist[u] + v.second < dist[v.first]) {
                se.erase(make_pair(dist[v.first], v.first));
                dist[v.first] = dist[u] + v.second;
                se.insert(make_pair(dist[v.first], v.first));
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        ans += dist[i];
    }
    dist1[1] = 0;
    for (int i = 1; i <= n; i++) {
        se1.insert(make_pair(dist1[i], i));
    }
    while (!se1.empty()) {
        int u = se1.begin()->second;
        se1.erase(se1.begin());
        if (dist1[u] > 1 << 30) {
            break;
        }
        for (auto v : G1[u]) {
            if (dist1[u] + v.second < dist1[v.first]) {
                se1.erase(make_pair(dist1[v.first], v.first));
                dist1[v.first] = v.second + dist1[u];
                se1.insert(make_pair(dist1[v.first], v.first));
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        ans += dist1[i];
    }
    cout << ans << '\n';

    return 0;
}

bellman ford:

#include <bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<n;i++)
using namespace std;
using LL = long long;

struct Edge {
    int x, y, v;
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    vector<Edge> G(m + 1), G1(m + 1); 
    for (int i = 1; i <= m; i++) {
        int u, v, c;
        cin >> u >> v >> c;
        G[i].x = u;
        G[i].y = v;
        G[i].v = c;
        G1[i].x = v;
        G1[i].y = u;
        G1[i].v = c;
    }
    vector<int> dist(n + 1, 0x3f3f3f3f);
    dist[1] = 0;
    while (true) {
        bool ok = false;
        for (int i = 1; i <= m; i++) {
            int x = G[i].x, y = G[i].y, w = G[i].v;
            if (dist[x] < 1 << 30) {
                if (dist[x] + w < dist[y]) {
                    dist[y] = dist[x] + w;
                    ok = true;
                }
            }
        }
        if (!ok) {
            break;
        }
    }
    vector<int> dist1(n + 1, 0x3f3f3f3f);
    dist1[1] = 0;
    while (true) {
        bool ok = false;
        for (int i = 1; i <= m; i++) {
            int x = G1[i].x, y = G1[i].y, w = G1[i].v;
            if (dist1[x] < 1 << 30) {
                if (dist1[x] + w < dist1[y]) {
                    dist1[y] = w + dist1[x];
                    ok = true;
                }
            }
        }
        if (!ok) {
            break;
        }
    }
    LL ans = 0;
    for (int i = 2; i <= n; i++) {
        ans += dist1[i] + dist[i];
    }
    cout << ans << '\n';

    return 0;
}

floyd (n>=1000慎用,该题吸氧可过):

#include <bits/stdc++.h>
#define rep(i,a,n) for(int i=a;i<n;i++)
using namespace std;
using LL = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    vector<vector<int>> a(n + 1, vector<int> (n + 1, 0x3f3f3f3f));
    rep (i, 0, m) {
        int u, v, c;
        cin >> u >> v >> c;
        a[u][v] = min(a[u][v], c);
    }
    for (int k = 1; k <= n; k++) {
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                a[i][j] = min(a[i][j], a[i][k] + a[k][j]);
            }
        }
    }
    LL ans = 0;
    for (int i = 2; i <= n; i++) {
        ans = ans + a[1][i] + a[i][1];
    }
    cout << ans << '\n';

    return 0;
}

关于spfa,它已经死了,请不要在任何公共场合写spfa

原网站

版权声明
本文为[eyuhaobanga]所创,转载请带上原文链接,感谢
https://blog.csdn.net/eyuhaobanga/article/details/126242674