圖論演算法模板
阿新 • • 發佈:2018-11-13
Under the bridge downtown
Forgot about my love
Under the bridge downtown
I gave my life away
Luogu P4779【模板】單源最短路徑(標準版)
//時間複雜度O((n+m)log2n) #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> usingnamespace 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; }
晚點填坑