1. 程式人生 > >圖論演算法模板

圖論演算法模板

Under the bridge downtown

Forgot about my love

Under the bridge downtown

I gave my life away

Luogu P4779【模板】單源最短路徑(標準版)

//時間複雜度O((n+m)log2​n)
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

using
namespace std; inline int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x *= 10; x += ch - '0'; ch = getchar(); } return x * f; } const int maxn = 100000 + 100; int n, m, s, dist[maxn];
struct Edge { int v, w; }; vector<Edge> g[maxn]; struct fow { int u, dist; bool operator< (const fow& f) const { return dist > f.dist; } }; priority_queue<fow> pq; /* 另外一種寫法: struct fow { int v, w; }; struct cmp { bool operator()(fow f1, fow f2) { return f1.w > f2.w; } }; priority_queue<fow, vector<fow>, cmp> pq; 注意pq使用的是>來表示<
*/ inline void dijkstra(int s) { memset(dist, 0x3f, sizeof dist); pq.push(fow { s, 0 }); dist[s] = 0; while (!pq.empty()) { int u = pq.top().u, dis = pq.top().dist; pq.pop(); if (dist[u] != dis) continue; //懶刪除是複雜度保證,去掉這行就會TLE for (int i = 0; i < g[u].size(); i++) { int v = g[u][i].v, w = g[u][i].w; if (dist[u] + w < dist[v]) { dist[v] = dist[u] + w; pq.push(fow { v, dist[v] }); } } } } int main() { n = read(); m = read(); s = read(); for (int i = 1; i <= m; i++) { int a, b, c; a = read(); b = read(); c = read(); g[a].push_back(Edge { b, c }); } dijkstra(s); for (int i = 1; i <= n; i++) cout << dist[i] << " "; cout << endl; return 0; }

 

luogu P3379 【模板】最近公共祖先(LCA)

還有優化空間,沒有改鄰接表(T了3個點)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

inline int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x *= 10; x += ch - '0'; ch = getchar(); }
    return x * f;
}

const int maxn = 500000 + 100, maxpow = 20;
int n, m, s, p[maxn][50], dep[maxn], _pow[50], lg[maxn];
vector<int> g[maxn * 2];

void dfs(int u, int fa) {
    for (int i = 1; (1 << i) <= dep[u]; i++) {
        p[u][i] = p[p[u][i - 1]][i - 1];
    }
    for (int i = 0; i < g[u].size(); i++) {
        int v = g[u][i];
        if (v == fa) continue;
        p[v][0] = u; dep[v] = dep[u] + 1;
        dfs(v, u);
    }
}

inline int lca(int x, int y) {
    if (dep[x] < dep[y]) swap(x, y);
    while (dep[x] > dep[y]) { x = p[x][lg[dep[x] - dep[y]] - 1]; }
    if (x == y) return x;
    for (int i = lg[dep[x]] - 1; i >= 0; i--) {
        if (p[x][i] == p[y][i]) continue;
        x = p[x][i]; y = p[y][i];
    }
    return p[x][0];
}

int main() {
    ios::sync_with_stdio(false);
    n = read(); m = read(); s = read();
    for (int i = 0; i <= 31; i++) _pow[i] = 1 << i;
    for (int i = 1; i <= n; i++) lg[i] = lg[i - 1] + (1 << lg[i - 1] == i); //預處理log2
    for (int i = 1; i < n; i++) {
        int a = read(), b = read();
        g[a].push_back(b); g[b].push_back(a);
    }
    p[s][0] = s;
    dfs(s, -1);
    for (int i = 1; i <= m; i++) { int x = read(), y = read(); cout << lca(x, y) << endl; }
    return 0;
}

 

晚點填坑