22527 鄭竣陽
Brine
BrineTW#7355
Index[0]
Index[1]
Index[2]
Index[3]
Glossary
所以什麼是圖?
邊
的路徑Graph Storage
int main() { int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; vector< vector<bool> > graph; graph.assign(vertexCount, vector<bool>(vertexCount)); int u, v; for (int i = 0; i < edgeCount; i++) { cin >> u >> v; graph[u][v] = graph[v][u] = 1; } }
空間複雜度?
int main() { int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; vector< vector<int> > graph(vertexCount); int u, v; for (int i = 0; i < edgeCount; i++) { cin >> u >> v; graph[u].push_back(v); graph[v].push_back(u); } }
cin >> u >> v; graph[u].push_back(v); graph[v].push_back(u);
cin >> u >> v; graph[u].push_back(v);
cin >> u >> v; graph[u][v] = 1; graph[v][u] = 1;
cin >> u >> v; graph[u][v] = 1;
會用 pair<int, int> 是因為有內建比較函式
typedef pair<int, int> Edge; int main() { int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; vector< vector<Edge> > graph(vertexCount); int u, v, w; // w is for weight for (int i = 0; i < edgeCount; i++) { cin >> u >> v >> w; graph[u].push_back({w, v}); graph[v].push_back({w, u}); } }
p.first 和 p.second 不好打?
用 priority_queue 會有問題,但很難寫
struct E { int to; int w; }; int main() { priority_queue<E, vector<E>, function<bool(E, E)> > pq( [](const E& a, const E& b) { return (a.w != b.w ? a.w < b.w : a.to < b.to); } ); }
項目 | 鄰接矩陣 | 鄰接串列 |
---|---|---|
空間複雜度 | ||
插入邊 | ||
查詢邊 | ||
枚舉邊 |
Other Methods
#include <iostream> using namespace std; int main() { int height, length; cin >> height >> length; vector<string> graph(height); for (auto& s: graph) cin >> s; }
int main() { int height, length; cin >> height >> length; vector<vector<int>> graph(height + 2, vector<int>(length + 2, -1)); for (int i = 1; i <= height; i++) { for (int j = 1; j <= length; j++) { cin >> graph[i][j]; if (graph[i][j]) graph[i][j] = -1; } } }
#include <bits/stdc++.h> using namespace std; int main() { int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; vector< pair<int, int> > edgeList(edgeCount); for (auto& [u, v]: edgeList) { cin >> u >> v; } }
Graph Traversal
我們現在有某個點突然有很多的水的一張圖,而我們現在想要計算出這張圖中的點何時會被水淹到,該怎麼做呢?
我們現在有某個點突然有很多的水的一張圖,而我們現在想要計算出這張圖中的點何時會被水淹到,該怎麼做呢?
我們現在有某個點突然有很多的水的一張圖,而我們現在想要計算出這張圖中的點何時會被水淹到,該怎麼做呢?
我們現在有某個點突然有很多的水的一張圖,而我們現在想要計算出這張圖中的點何時會被水淹到,該怎麼做呢?
我們現在有某個點突然有很多的水的一張圖,而我們現在想要計算出這張圖中的點何時會被水淹到,該怎麼做呢?
我們現在有某個點突然有很多的水的一張圖,而我們現在想要計算出這張圖中的點何時會被水淹到,該怎麼做呢?
vector<int> bfs(int source, vector< vector<int> >& graph) { queue<int> q; q.push(source); vector<int> distance(graph.size(), INT32_MAX); distance[source] = 0; while (!q.empty()) { // while (q.size()) int& current = q.front(); for (auto& n: graph[current]) { if (distance[n] != INT32_MAX) continue; distance[n] = distance[current] + 1; q.push(n); } q.pop(); } distance[source] = 0; return distance; }
四個方向的
while (!q.empty()) { // while (q.size()) auto& [x, y] = q.front(); // queue< pair<int, int> > q; if (graph[x][y + 1] == INT32_MAX) { graph[x][y + 1] = graph[x][y] + 1; q.push({x, y + 1}); } if (graph[x][y - 1] == INT32_MAX) { graph[x][y - 1] = graph[x][y] + 1; q.push({x, y - 1}); } if (graph[x + 1][y] == INT32_MAX) { graph[x + 1][y] = graph[x][y] + 1; q.push({x + 1, y}); } if (graph[x - 1][y] == INT32_MAX) { graph[x - 1][y] = graph[x][y] + 1; q.push({x - 1, y}); } q.pop(); }
const int dx[] = {1,-1, 0, 0}; const int dy[] = {0, 0, 1,-1}; while (!q.empty()) { auto& [x, y] = q.front(); for (int i = 0; i < 4; i++) { auto& nextPosition = graph[x + dx[i]][y + dy[i]]; if (nextPosition == INT32_MAX) { nextPosition = graph[x][y] + 1; q.push({x + dx[i], y + dy[i]}); } } q.pop(); }
void dfs(int current, vector< vector<int> >& graph, vector<bool>& visited) { visited[current] = 1; for (auto& n: graph[current]) { if (visited[n]) continue; dfs(n, graph, visited); } } int main() { int vC, eC; cin >> vC >> eC; vector< vector<int> > graph(vC); int u, v; for (int i = 0; i < eC; i++) { cin >> u >> v; graph[u].push_back(v); } vector<bool> visited(vC); dfs(0, graph, visited); }
void dfs(int current, vector< vector<int> >& graph, vector<bool>& visited) { visited[current] = 1; for (auto& n: graph[current]) { if (visited[n]) continue; dfs(n, graph, visited); } } int main() { int vC, eC; cin >> vC >> eC; vector< vector<int> > graph(vC); int u, v; for (int i = 0; i < eC; i++) { cin >> u >> v; graph[u].push_back(v); } vector<bool> visited(vC); dfs(0, graph, visited); }
void dfs(int current, vector< vector<int> >& graph, vector<bool>& visited) { visited[current] = 1; for (auto& n: graph[current]) { if (visited[n]) continue; dfs(n, graph, visited); } } int main() { int vC, eC; cin >> vC >> eC; vector< vector<int> > graph(vC); int u, v; for (int i = 0; i < eC; i++) { cin >> u >> v; graph[u].push_back(v); } vector<bool> visited(vC); dfs(0, graph, visited); }
vector<bool> visited(vC); function<void(int)> dfs = [&](int current) { visited[current] = 1; for (auto& n: graph[current]) { if (!visited[n]) dfs(n); } };
vector< pair<int, int> > tree(vC); int leftChild, rightChild; for (int i = 0; i < vC; i++) { cin >> leftChild >> rightChild; tree[i] = {leftChild, rightChild}; } vector<int> preorder, inorder, postorder; function<void(int)> dfs = [&](int current) { auto [l, r] = tree[current]; preorder.push_back(current); if (l >= 0) dfs(l); inorder.push_back(current); if (r >= 0) dfs(r); postorder.push_back(current); };
vector< pair<int, int> > tree(vC); int leftChild, rightChild; for (int i = 0; i < vC; i++) { cin >> leftChild >> rightChild; tree[i] = {leftChild, rightChild}; } vector<int> preorder, inorder, postorder; function<void(int)> dfs = [&](int current) { auto [l, r] = tree[current]; preorder.push_back(current); if (l >= 0) dfs(l); inorder.push_back(current); if (r >= 0) dfs(r); postorder.push_back(current); };
vector< pair<int, int> > tree(vC); int leftChild, rightChild; for (int i = 0; i < vC; i++) { cin >> leftChild >> rightChild; tree[i] = {leftChild, rightChild}; } vector<int> preorder, inorder, postorder; function<void(int)> dfs = [&](int current) { auto [l, r] = tree[current]; preorder.push_back(current); if (l >= 0) dfs(l); inorder.push_back(current); if (r >= 0) dfs(r); postorder.push_back(current); };
Topological Sort
vector<int> topologicalSort(vector< vector<int> >& graph) { vector<int> indegree(graph.size()); for (auto& v: graph) for (auto& n: v) indegree[n]++; vector<int> order; order.reserve(graph.size()); queue<int> q; for (int i = 0; i < graph.size(); i++) { if (indegree[i] == 0) q.push(i); } while (!q.empty()) { auto& current = q.front(); order.push_back(current); for (auto& n: graph[current]) { if (--indegree[n] == 0) q.push(n); } } return order; }
vector<int> topologicalSort(vector< vector<int> >& graph) { vector<int> indegree(graph.size()); for (auto& v: graph) for (auto& n: v) indegree[n]++; vector<int> order; order.reserve(graph.size()); queue<int> q; for (int i = 0; i < graph.size(); i++) { if (indegree[i] == 0) q.push(i); } while (!q.empty()) { auto& current = q.front(); order.push_back(current); for (auto& n: graph[current]) { if (--indegree[n] == 0) q.push(n); } } return order; }
vector<int> topologicalSort(vector< vector<int> >& graph) { vector<int> indegree(graph.size()); for (auto& v: graph) for (auto& n: v) indegree[n]++; vector<int> order; order.reserve(graph.size()); queue<int> q; for (int i = 0; i < graph.size(); i++) { if (indegree[i] == 0) q.push(i); } while (!q.empty()) { auto& current = q.front(); order.push_back(current); for (auto& n: graph[current]) { if (--indegree[n] == 0) q.push(n); } } return order; }
vector<int> topologicalSort(vector< vector<int> >& graph) { vector<int> indegree(graph.size()); for (auto& v: graph) for (auto& n: v) indegree[n]++; vector<int> order; order.reserve(graph.size()); queue<int> q; for (int i = 0; i < graph.size(); i++) { if (indegree[i] == 0) q.push(i); } while (!q.empty()) { auto& current = q.front(); order.push_back(current); for (auto& n: graph[current]) { if (--indegree[n] == 0) q.push(n); } } return order; }
vector<int> topologicalSort(vector< vector<int> >& graph) { vector<int> indegree(graph.size()); for (auto& v: graph) for (auto& n: v) indegree[n]++; vector<int> order; order.reserve(graph.size()); queue<int> q; for (int i = 0; i < graph.size(); i++) { if (indegree[i] == 0) q.push(i); } while (!q.empty()) { auto& current = q.front(); order.push_back(current); for (auto& n: graph[current]) { if (--indegree[n] == 0) q.push(n); } } return order; }
vector<int> topologicalSort(vector< vector<int> >& graph) { vector<int> indegree(graph.size()); for (auto& v: graph) for (auto& n: v) indegree[n]++; vector<int> order; order.reserve(graph.size()); queue<int> q; for (int i = 0; i < graph.size(); i++) { if (indegree[i] == 0) q.push(i); } while (!q.empty()) { auto& current = q.front(); order.push_back(current); for (auto& n: graph[current]) { if (--indegree[n] == 0) q.push(n); } } return order; }
vector<int> topologicalSort(vector< vector<int> >& graph) { vector<int> order; order.reserve(graph.size()); vector<int> visited(graph.size()); bool cyclic = false; function<void(int, int&)> dfs = [&](int now, int& s) { if (cyclic) return; visited[now] = s; for (auto& n: graph[now]) { if (visited[n] == s) { cyclic = true; return; } if (!visited[n]) dfs(n, s); } order.push_back(now); }; for (int i = 0; i < graph.size(); i++) dfs(i, i); if (cyclic) return vector<int>(0); reverse(order.begin(), order.end()); return order; }
vector<int> topologicalSort(vector< vector<int> >& graph) { vector<int> order; order.reserve(graph.size()); vector<int> visited(graph.size()); bool cyclic = false; function<void(int, int&)> dfs = [&](int now, int& s) { if (cyclic) return; visited[now] = s; for (auto& n: graph[now]) { if (visited[n] == s) { cyclic = true; return; } if (!visited[n]) dfs(n, s); } order.push_back(now); }; for (int i = 0; i < graph.size(); i++) dfs(i, i); if (cyclic) return vector<int>(0); reverse(order.begin(), order.end()); return order; }
vector<int> topologicalSort(vector< vector<int> >& graph) { vector<int> order; order.reserve(graph.size()); vector<int> visited(graph.size()); bool cyclic = false; function<void(int, int&)> dfs = [&](int now, int& s) { if (cyclic) return; visited[now] = s; for (auto& n: graph[now]) { if (visited[n] == s) { cyclic = true; return; } if (!visited[n]) dfs(n, s); } order.push_back(now); }; for (int i = 0; i < graph.size(); i++) dfs(i, i); if (cyclic) return vector<int>(0); reverse(order.begin(), order.end()); return order; }
vector<int> topologicalSort(vector< vector<int> >& graph) { vector<int> order; order.reserve(graph.size()); vector<int> visited(graph.size()); bool cyclic = false; function<void(int, int&)> dfs = [&](int now, int& s) { if (cyclic) return; visited[now] = s; for (auto& n: graph[now]) { if (visited[n] == s) { cyclic = true; return; } if (!visited[n]) dfs(n, s); } order.push_back(now); }; for (int i = 0; i < graph.size(); i++) dfs(i, i); if (cyclic) return vector<int>(0); reverse(order.begin(), order.end()); return order; }
vector<int> topologicalSort(vector< vector<int> >& graph) { vector<int> order; order.reserve(graph.size()); vector<int> visited(graph.size()); bool cyclic = false; function<void(int, int&)> dfs = [&](int now, int& s) { if (cyclic) return; visited[now] = s; for (auto& n: graph[now]) { if (visited[n] == s) { cyclic = true; return; } if (!visited[n]) dfs(n, s); } order.push_back(now); }; for (int i = 0; i < graph.size(); i++) dfs(i, i); if (cyclic) return vector<int>(0); reverse(order.begin(), order.end()); return order; }
function<void(int, const int&)> dfs = [&](int now, const int s) { if (cyclic || visited[now]) return; visited[now] = s; for (auto& n: graph[now]) { if (visited[n] == s) { cyclic = true; return; } if (!visited[n]) dfs(n, s); } order.push_back(now); }; for (int i = 0; i < graph.size(); i++) dfs(i, i+1);
function<void(int, const int&)> dfs = [&](int now, const int s) { if (cyclic || visited[now]) return; visited[now] = s; for (auto& n: graph[now]) { if (visited[n] == s) { cyclic = true; return; } if (!visited[n]) dfs(n, s); } order.push_back(now); }; for (int i = 0; i < graph.size(); i++) dfs(i, i+1);
function<void(int, const int&)> dfs = [&](int now, const int s) { if (cyclic || visited[now]) return; visited[now] = s; for (auto& n: graph[now]) { if (visited[n] == s) { cyclic = true; return; } if (!visited[n]) dfs(n, s); } order.push_back(now); }; for (int i = 0; i < graph.size(); i++) dfs(i, i+1);
Disjoint Set
vector<int> master(vertexCount); int query(int i) { if (master[i] == i) return i; return query(master[i]); }
int query(int i) { return (master[i] == i ? i : query(master[i])); }
int query(int i) { if (master[i] == i) return i; master[i] = query(master[i]); return master[i]; }
struct DisjointSet { vector<int> master, depth; disjointSet(int vertexCount) { master.resize(vertexCount); depth.resize(vertexCount); for (int i = 0; i < vertexCount; i++) { master[i] = i; depth[i] = 1; } } int query(int i) { if (master[i] == i) return i; return master[i] = query(master[i]); } void merge(int a, int b) { a = query(a); b = query(b); if (a == b) return; if (depth[a] < depth[b]) swap(a, b); master[b] = a; depth[a] += depth[b]; } }; // 記得分號
struct DisjointSet { vector<int> master, depth; disjointSet(int vertexCount) { master.resize(vertexCount); depth.resize(vertexCount); for (int i = 0; i < vertexCount; i++) { master[i] = i; depth[i] = 1; } } int query(int i) { if (master[i] == i) return i; return master[i] = query(master[i]); } void merge(int a, int b) { a = query(a); b = query(b); if (a == b) return; if (depth[a] < depth[b]) swap(a, b); master[b] = a; depth[a] += depth[b]; } }; // 記得分號
struct DisjointSet { vector<int> master, depth; disjointSet(int vertexCount) { master.resize(vertexCount); depth.resize(vertexCount); for (int i = 0; i < vertexCount; i++) { master[i] = i; depth[i] = 1; } } int query(int i) { if (master[i] == i) return i; return master[i] = query(master[i]); } void merge(int a, int b) { a = query(a); b = query(b); if (a == b) return; if (depth[a] < depth[b]) swap(a, b); master[b] = a; depth[a] += depth[b]; } }; // 記得分號
struct DisjointSet { vector<int> master, depth; disjointSet(int vertexCount) { master.resize(vertexCount); depth.resize(vertexCount); for (int i = 0; i < vertexCount; i++) { master[i] = i; depth[i] = 1; } } int query(int i) { if (master[i] == i) return i; return master[i] = query(master[i]); } void merge(int a, int b) { a = query(a); b = query(b); if (a == b) return; if (depth[a] < depth[b]) swap(a, b); master[b] = a; depth[a] += depth[b]; } }; // 記得分號
struct DisjointSet { vector<int> master, depth; disjointSet(int vertexCount) { master.resize(vertexCount); depth.resize(vertexCount); for (int i = 0; i < vertexCount; i++) { master[i] = i; depth[i] = 1; } } int query(int i) { if (master[i] == i) return i; return master[i] = query(master[i]); } void merge(int a, int b) { a = query(a); b = query(b); if (a == b) return; if (depth[a] < depth[b]) swap(a, b); master[b] = a; depth[a] += depth[b]; } }; // 記得分號
Lowest Common Ancestor
我發現樹論會講,這裡先講其中一種作法就好了
vector< vector<int> > ancestor; for (int j = 1; j <= __lg(maxDepth); j++) { for (int i = 0; i < vertexCount; i++) { ancestor[i][j] = ancestor[ancestor[i][j - 1]][j - 1]; } }
vector<int> depth(vC); function<void(int, int)> dfs = [&](int current, int d = 1) { depth[current] = d++; for (auto& n: graph[current]) { if (depth[n]) continue; dfs(n, d); } };
function<int(int, int)> lca = [&](int u, int v) { if (depth[u] < depth[v]) swap(u, v); if (depth[u] != depth[v]) { int dif = depth[u] - depth[v]; for (int i = 0; dif > 0; i++) { if (dif & 1) u = ancestor[u][i]; dif >>= 1; } } for (int i = __lg(maxDepth); i >= 0; i--) { if (ancestor[u][i] != ancestor[v][i]) { u = ancestor[u][i]; v = ancestor[v][i]; } } return ancestor[u][0]; };
#include <bits/stdc++.h> using namespace std; int main() { int vertexCount, query; cin >> vertexCount >> query; vector< vector<int> > graph(vertexCount); int a, b; for (int i = 1; i < vertexCount; i++) { cin >> a >> b; graph[a].push_back(b); graph[b].push_back(a); } vector< vector<int> > ancestor(vertexCount, vector<int>(1)); vector<int> depth(vertexCount); function<void(int, int)> dfs = [&](int current, int d) { depth[current] = d++; for (auto& n: graph[current]) { if (depth[n]) continue; ancestor[n][0] = current; dfs(n, d); } }; dfs(0, 1); int maxDepth = 0; for (auto& n: depth) maxDepth = max(maxDepth, n); for (auto& v: ancestor) v.resize(__lg(maxDepth) + 1); for (int j = 1; j <= __lg(maxDepth); j++) { for (int i = 0; i < vertexCount; i++) { ancestor[i][j] = ancestor[ancestor[i][j - 1]][j - 1]; } } function<int(int, int)> lca = [&](int u, int v) { if (depth[u] < depth[v]) swap(u, v); if (depth[u] != depth[v]) { int dif = depth[u] - depth[v]; for (int i = 0; dif > 0; i++) { if (dif & 1) u = ancestor[u][i]; dif >>= 1; } } if (u == v) return u; for (int i = __lg(maxDepth); i >= 0; i--) { if (ancestor[u][i] != ancestor[v][i]) { u = ancestor[u][i]; v = ancestor[v][i]; } } return ancestor[u][0]; }; while (query--) { cin >> a >> b; cout << lca(a, b) << '\n'; } }
Spanning Tree
typedef pair<int, int> pii; typedef pair<int, pii> pi_ii; struct DisjointSet { vector<int> master; DisjointSet(int vertexCount) { master.resize(vertexCount); iota(master.begin(), master.end(), 0); } int query(int a) { if (a == master[a]) return a; return master[a] = query(master[a]); } bool connected(int a, int b) { return query(a) == query(b); } void merge(int a, int b) { master[query(a)] = master[b]; } }; int kruskal(vector<pi_ii>& minEdge, DisjointSet& ds) { int cost = 0; for (auto& [w, uv]: minEdge) { auto& [u, v] = uv; if (ds.connected(u, v)) continue; ds.merge(u, v); cost += w; } return cost; } int main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; DisjointSet ds(vertexCount); vector<pi_ii> minEdge(edgeCount); for (auto& [w, uv]: minEdge) { auto& [u, v] = uv; cin >> u >> v >> w; } sort(minEdge.begin(), minEdge.end()); cout << kruskal(minEdge, ds) << '\n'; }
typedef pair<int, int> pii; typedef pair<int, pii> pi_ii; struct DisjointSet { vector<int> master; DisjointSet(int vertexCount) { master.resize(vertexCount); iota(master.begin(), master.end(), 0); } int query(int a) { if (a == master[a]) return a; return master[a] = query(master[a]); } bool connected(int a, int b) { return query(a) == query(b); } void merge(int a, int b) { master[query(a)] = master[b]; } }; int kruskal(vector<pi_ii>& minEdge, DisjointSet& ds) { int cost = 0; for (auto& [w, uv]: minEdge) { auto& [u, v] = uv; if (ds.connected(u, v)) continue; ds.merge(u, v); cost += w; } return cost; } int main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; DisjointSet ds(vertexCount); vector<pi_ii> minEdge(edgeCount); for (auto& [w, uv]: minEdge) { auto& [u, v] = uv; cin >> u >> v >> w; } sort(minEdge.begin(), minEdge.end()); cout << kruskal(minEdge, ds) << '\n'; }
typedef pair<int, int> pii; typedef pair<int, pii> pi_ii; struct DisjointSet { vector<int> master; DisjointSet(int vertexCount) { master.resize(vertexCount); iota(master.begin(), master.end(), 0); } int query(int a) { if (a == master[a]) return a; return master[a] = query(master[a]); } bool connected(int a, int b) { return query(a) == query(b); } void merge(int a, int b) { master[query(a)] = master[b]; } }; int kruskal(vector<pi_ii>& minEdge, DisjointSet& ds) { int cost = 0; for (auto& [w, uv]: minEdge) { auto& [u, v] = uv; if (ds.connected(u, v)) continue; ds.merge(u, v); cost += w; } return cost; } int main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; DisjointSet ds(vertexCount); vector<pi_ii> minEdge(edgeCount); for (auto& [w, uv]: minEdge) { auto& [u, v] = uv; cin >> u >> v >> w; } sort(minEdge.begin(), minEdge.end()); cout << kruskal(minEdge, ds) << '\n'; }
typedef pair<int, int> pii; typedef pair<int, pii> pi_ii; struct DisjointSet { vector<int> master; DisjointSet(int vertexCount) { master.resize(vertexCount); iota(master.begin(), master.end(), 0); } int query(int a) { if (a == master[a]) return a; return master[a] = query(master[a]); } bool connected(int a, int b) { return query(a) == query(b); } void merge(int a, int b) { master[query(a)] = master[b]; } }; int kruskal(vector<pi_ii>& minEdge, DisjointSet& ds) { int cost = 0; for (auto& [w, uv]: minEdge) { auto& [u, v] = uv; if (ds.connected(u, v)) continue; ds.merge(u, v); cost += w; } return cost; } int main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; DisjointSet ds(vertexCount); vector<pi_ii> minEdge(edgeCount); for (auto& [w, uv]: minEdge) { auto& [u, v] = uv; cin >> u >> v >> w; } sort(minEdge.begin(), minEdge.end()); cout << kruskal(minEdge, ds) << '\n'; }
typedef pair<int, int> pii; typedef pair<int, pii> pi_ii; struct DisjointSet { vector<int> master; DisjointSet(int vertexCount) { master.resize(vertexCount); iota(master.begin(), master.end(), 0); } int query(int a) { if (a == master[a]) return a; return master[a] = query(master[a]); } bool connected(int a, int b) { return query(a) == query(b); } void merge(int a, int b) { master[query(a)] = master[b]; } }; int kruskal(vector<pi_ii>& minEdge, DisjointSet& ds) { int cost = 0; for (auto& [w, uv]: minEdge) { auto& [u, v] = uv; if (ds.connected(u, v)) continue; ds.merge(u, v); cost += w; } return cost; } int main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; DisjointSet ds(vertexCount); vector<pi_ii> minEdge(edgeCount); for (auto& [w, uv]: minEdge) { auto& [u, v] = uv; cin >> u >> v >> w; } sort(minEdge.begin(), minEdge.end()); cout << kruskal(minEdge, ds) << '\n'; }
typedef pair<int, int> pii; int prim(vector< vector<pii> >& graph) { priority_queue<pii, vector<pii>, greater<pii> > pq; vector<int> currentMinCost(graph.size(), INT32_MAX); vector<bool> inside(graph.size(), false); int sum = 0; pq.push({0, 0}); currentMinCost[0] = 0; while (!pq.empty()) { auto [w, u] = pq.top(); pq.pop(); if (inside[u]) continue; inside[u] = true; sum += w; for (auto& [w, v]: graph[u]) { if (!inside[v] && currentMinCost[v] > w) { currentMinCost[v] = w; pq.push({w, v}); } } } return sum; } int main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; vector< vector<pii> > graph(vertexCount); int u, v, w; for (int i = 0; i < edgeCount; i++) { cin >> u >> v >> w; graph[u].push_back({w, v}); graph[v].push_back({w, u}); } cout << prim(graph) << '\n'; }
typedef pair<int, int> pii; int prim(vector< vector<pii> >& graph) { priority_queue<pii, vector<pii>, greater<pii> > pq; vector<int> currentMinCost(graph.size(), INT32_MAX); vector<bool> inside(graph.size(), false); int sum = 0; pq.push({0, 0}); currentMinCost[0] = 0; while (!pq.empty()) { auto [w, u] = pq.top(); pq.pop(); if (inside[u]) continue; inside[u] = true; sum += w; for (auto& [w, v]: graph[u]) { if (!inside[v] && currentMinCost[v] > w) { currentMinCost[v] = w; pq.push({w, v}); } } } return sum; } int main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; vector< vector<pii> > graph(vertexCount); int u, v, w; for (int i = 0; i < edgeCount; i++) { cin >> u >> v >> w; graph[u].push_back({w, v}); graph[v].push_back({w, u}); } cout << prim(graph) << '\n'; }
typedef pair<int, int> pii; int prim(vector< vector<pii> >& graph) { priority_queue<pii, vector<pii>, greater<pii> > pq; vector<int> currentMinCost(graph.size(), INT32_MAX); vector<bool> inside(graph.size(), false); int sum = 0; pq.push({0, 0}); currentMinCost[0] = 0; while (!pq.empty()) { auto [w, u] = pq.top(); pq.pop(); if (inside[u]) continue; inside[u] = true; sum += w; for (auto& [w, v]: graph[u]) { if (!inside[v] && currentMinCost[v] > w) { currentMinCost[v] = w; pq.push({w, v}); } } } return sum; } int main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; vector< vector<pii> > graph(vertexCount); int u, v, w; for (int i = 0; i < edgeCount; i++) { cin >> u >> v >> w; graph[u].push_back({w, v}); graph[v].push_back({w, u}); } cout << prim(graph) << '\n'; }
typedef pair<int, int> pii; int prim(vector< vector<pii> >& graph) { priority_queue<pii, vector<pii>, greater<pii> > pq; vector<int> currentMinCost(graph.size(), INT32_MAX); vector<bool> inside(graph.size(), false); int sum = 0; pq.push({0, 0}); currentMinCost[0] = 0; while (!pq.empty()) { auto [w, u] = pq.top(); pq.pop(); if (inside[u]) continue; inside[u] = true; sum += w; for (auto& [w, v]: graph[u]) { if (!inside[v] && currentMinCost[v] > w) { currentMinCost[v] = w; pq.push({w, v}); } } } return sum; } int main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; vector< vector<pii> > graph(vertexCount); int u, v, w; for (int i = 0; i < edgeCount; i++) { cin >> u >> v >> w; graph[u].push_back({w, v}); graph[v].push_back({w, u}); } cout << prim(graph) << '\n'; }
typedef pair<int, int> pii; int prim(vector< vector<pii> >& graph) { priority_queue<pii, vector<pii>, greater<pii> > pq; vector<int> currentMinCost(graph.size(), INT32_MAX); vector<bool> inside(graph.size(), false); int sum = 0; pq.push({0, 0}); currentMinCost[0] = 0; while (!pq.empty()) { auto [w, u] = pq.top(); pq.pop(); if (inside[u]) continue; inside[u] = true; sum += w; for (auto& [w, v]: graph[u]) { if (!inside[v] && currentMinCost[v] > w) { currentMinCost[v] = w; pq.push({w, v}); } } } return sum; } int main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; vector< vector<pii> > graph(vertexCount); int u, v, w; for (int i = 0; i < edgeCount; i++) { cin >> u >> v >> w; graph[u].push_back({w, v}); graph[v].push_back({w, u}); } cout << prim(graph) << '\n'; }
typedef pair<int, int> pii; int prim(vector< vector<pii> >& graph) { priority_queue<pii, vector<pii>, greater<pii> > pq; vector<int> currentMinCost(graph.size(), INT32_MAX); vector<bool> inside(graph.size(), false); int sum = 0; pq.push({0, 0}); currentMinCost[0] = 0; while (!pq.empty()) { auto [w, u] = pq.top(); pq.pop(); if (inside[u]) continue; inside[u] = true; sum += w; for (auto& [w, v]: graph[u]) { if (!inside[v] && currentMinCost[v] > w) { currentMinCost[v] = w; pq.push({w, v}); } } } return sum; } int main() { ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); int vertexCount, edgeCount; cin >> vertexCount >> edgeCount; vector< vector<pii> > graph(vertexCount); int u, v, w; for (int i = 0; i < edgeCount; i++) { cin >> u >> v >> w; graph[u].push_back({w, v}); graph[v].push_back({w, u}); } cout << prim(graph) << '\n'; }
Shortest Path
vector< vector<int> > d(vC, vector<int>(vC, 1e9 + 225)); for (int i = 0; i < vC; i++) d[i][i] = 0; int u, v, w; for (int i = 0; i < eC; i++) { cin >> u >> v >> w; d[u][v] = min(d[u][v], w); } for (int k = 0; k < vC; k++) { for (int i = 0; i < vC; i++) { for (int j = 0; j < vC; j++) { d[i][j] = min(d[i][j], d[i][k] + d[k][j]); } } }
struct Edge { int u, v, w; }; vector<int> Bellman_Ford(int vertexCount, int source, vector<Edge>& edge) { vector<int> distance(vertexCount, INT32_MAX); distance[source] = 0; for (int i = 1; i < vertexCount; i++) { for (auto& [u, v, w]: edge) { distance[u] = min(distance[u], distance[v] + w); distance[v] = min(distance[v], distance[u] + w); } } return distance; }
struct Edge { int u, v, w; }; vector<int> Bellman_Ford(int vertexCount, int source, vector<Edge>& edge) { vector<int> distance(vertexCount, INT32_MAX); distance[source] = 0; for (int i = 1; i < vertexCount; i++) { for (auto& [u, v, w]: edge) { distance[u] = min(distance[u], distance[v] + w); distance[v] = min(distance[v], distance[u] + w); } } return distance; }
typedef pair<int, int> pii; vector<int> SPFA(vector< vector<pii>& graph, int source) { vector<int> distance(graph.size(), INT32_MAX); distance[source] = 0; queue<int> q; vector<bool> inQueue(graph.size(), 0); q.push(source); while (!q.empty()) { auto v = q.front(); q.pop(); inQueue[v] = 0; for (auto& [u, w]: graph[v]) { distance[u] = min(distance[u], distance[v] + w); if (inQueue[u]) continue; q.push(u); inQueue[u] = 1; } } return distance; }
typedef pair<int, int> pii; vector<int> SPFA(vector< vector<pii>& graph, int source) { vector<int> distance(graph.size(), INT32_MAX); distance[source] = 0; queue<int> q; vector<bool> inQueue(graph.size(), 0); q.push(source); while (!q.empty()) { auto v = q.front(); q.pop(); inQueue[v] = 0; for (auto& [u, w]: graph[v]) { distance[u] = min(distance[u], distance[v] + w); if (inQueue[u]) continue; q.push(u); inQueue[u] = 1; } } return distance; }
typedef pair<int, int> pii; vector<int> SPFA(vector< vector<pii>& graph, int source) { vector<int> distance(graph.size(), INT32_MAX); distance[source] = 0; queue<int> q; vector<bool> inQueue(graph.size(), 0); q.push(source); while (!q.empty()) { auto v = q.front(); q.pop(); inQueue[v] = 0; for (auto& [u, w]: graph[v]) { distance[u] = min(distance[u], distance[v] + w); if (inQueue[u]) continue; q.push(u); inQueue[u] = 1; } } return distance; }
typedef pair<int, int> pii; vector<int> SPFA(vector< vector<pii>& graph, int source) { vector<int> distance(graph.size(), INT32_MAX); distance[source] = 0; queue<int> q; vector<bool> inQueue(graph.size(), 0); q.push(source); while (!q.empty()) { auto v = q.front(); q.pop(); inQueue[v] = 0; for (auto& [u, w]: graph[v]) { distance[u] = min(distance[u], distance[v] + w); if (inQueue[u]) continue; q.push(u); inQueue[u] = 1; } } return distance; }
typedef pair<int, int> pii; vector<int> Dijkstra(vector< vector<pii> >& graph, int source) { vector<int> distance(graph.size(), INT32_MAX); distance[source] = 0; vector<bool> visited(graph.size(), 0); priority_queue<pii, vector<pii>, greater<pii> > pq; pq.push({0, source}); while (!pq.empty()) { auto [w, u] = pq.top(); pq.pop(); if (visited[u]) continue; visited[u] = 1; for (auto& [w, v]: graph[u]) { if (distance[v] <= distance[u] + w) continue; distance[v] = distance[u] + w; pq.push({distance[v], v}); } } return distance; }
typedef pair<int, int> pii; vector<int> Dijkstra(vector< vector<pii> >& graph, int source) { vector<int> distance(graph.size(), INT32_MAX); distance[source] = 0; vector<bool> visited(graph.size(), 0); priority_queue<pii, vector<pii>, greater<pii> > pq; pq.push({0, source}); while (!pq.empty()) { auto [w, u] = pq.top(); pq.pop(); if (visited[u]) continue; visited[u] = 1; for (auto& [w, v]: graph[u]) { if (distance[v] <= distance[u] + w) continue; distance[v] = distance[u] + w; pq.push({distance[v], v}); } } return distance; }
typedef pair<int, int> pii; vector<int> Dijkstra(vector< vector<pii> >& graph, int source) { vector<int> distance(graph.size(), INT32_MAX); distance[source] = 0; vector<bool> visited(graph.size(), 0); priority_queue<pii, vector<pii>, greater<pii> > pq; pq.push({0, source}); while (!pq.empty()) { auto [w, u] = pq.top(); pq.pop(); if (visited[u]) continue; visited[u] = 1; for (auto& [w, v]: graph[u]) { if (distance[v] <= distance[u] + w) continue; distance[v] = distance[u] + w; pq.push({distance[v], v}); } } return distance; }
typedef pair<int, int> pii; vector<int> Dijkstra(vector< vector<pii> >& graph, int source) { vector<int> distance(graph.size(), INT32_MAX); distance[source] = 0; vector<bool> visited(graph.size(), 0); priority_queue<pii, vector<pii>, greater<pii> > pq; pq.push({0, source}); while (!pq.empty()) { auto [w, u] = pq.top(); pq.pop(); if (visited[u]) continue; visited[u] = 1; for (auto& [w, v]: graph[u]) { if (distance[v] <= distance[u] + w) continue; distance[v] = distance[u] + w; pq.push({distance[v], v}); } } return distance; }
Connectivity
vector<int> low(vC); vector<int> preorder(vC); vector<bool> isCutVertex(vC); int counter = 0; function<void(int, int)> dfs = [&](int u, int last) { low[u] = preorder[u] = ++counter; int child = 0; for (auto& v: graph[u]) { if (v == last) continue; if (preorder[v]) { // is back edge low[u] = min(low[u], preorder[v]); } else { dfs(v, u); if (last >= 0 && low[v] >= preorder[u]) { isCutVertex[u] = true; } child++; low[u] = min(low[u], low[v]); } } if (last < 0 && child > 1) isCutVertex[u] = true; }; dfs(0, -1);
vector<int> low(vC); vector<int> order(vC); set<pii> isBridge; int counter = 0; function<void(int, int)> dfs = [&](int current, int last) { low[current] = order[current] = ++counter; for (auto& v: graph[current]) { if (v == last) continue; if (order[v]) { // is back edge low[current] = min(low[current], order[v]); // a back edge always forms a cycle } else { dfs(v, current); low[current] = min(low[current], low[v]); if (low[v] > order[current]) { isBridge.insert({current, v}); } } } }; dfs(0, -1);
Components
struct Edge { int a, b; Edge(int u = -1, int v = -1): a(u), b(v) {} }; vector< vector<int> > graph; vector<int> low, preorder; vector<int> isCutVertex; stack<Edge> s; vector<int> bccId; vector< vector<int> > bcc; int counter = 0; int bccCounter = 0; void dfs(int u, int p) { low[u] = preorder[u] = ++counter; int child = 0; for (auto& v: graph[u]) { Edge e(u, v); if (v == p) continue; s.push(e); if (preorder[v]) { low[u] = min(low[u], preorder[v]); continue; } child++; dfs(v, u); low[u] = min(low[u], low[v]); if (low[v] >= preorder[u]) { isCutVertex[u] = 1; ++bccCounter; Edge temp; do { temp = s.top(), s.pop(); if (bccId[temp.a] != bccCounter) bcc[bccCounter].push_back(temp.a); if (bccId[temp.b] != bccCounter) bcc[bccCounter].push_back(temp.b); bccId[temp.a] = bccId[temp.b] = bccCounter; } while (temp.a != u || temp.b != v); } } if (p <= 0 && child == 1) { isCutVertex[u] = 0; } }
vector< vector<int> > graph; vector<int> low, preorder; stack<int> s; vector<int> bccId; vector< vector<int> > bcc; int counter = 0; int bccCounter = 0; void dfs(int u, int p) { low[u] = preorder[u] = ++counter; s.push(u); for (auto& v: graph[u]) { if (v == p) continue; if (preorder[v]) { low[u] = min(low[u], preorder[v]); continue; } dfs(v, u); low[u] = min(low[u], low[v]); if (low[v] > preorder[u]) { ++bccCounter; int w; do { w = s.top(), s.pop(); bccId[w] = bccCounter; } while (w != u); } } if (p < 0) { ++bccCounter; int w; while (!s.empty()) { w = s.top(), s.pop(); bccId[w] = bccCounter; } } }
#include <bits/stdc++.h> using namespace std; vector<int> tarjan(vector< vector<int> >& graph) { vector<int> preorder(graph.size()); vector<int> low(graph.size()); vector<int> scc(graph.size()); stack<int> s; int counter = 0; int sccId = 0; function<void(int)> dfs = [&](int u) { preorder[u] = low[u] = ++counter; s.push(u); for (auto& v: graph[u]) { if (scc[v]) continue; if (preorder[v]) low[u] = min(low[u], preorder[v]); if (!preorder[v]) { dfs(v); low[u] = min(low[u], low[v]); } } if (low[u] == preorder[u]) { ++sccId; int v; do { v = s.top(), s.pop(); scc[v] = sccId; } while (u != v); } }; for (int i = 0; i < graph.size(); i++) if (!preorder[i]) dfs(i); return scc; }
void dfs(int current, vector<int>& postorder, vector<bool>& visited, vector< vector<int> >& graph) { visited[current] = 1; for (auto& v: graph[current]) { if (visited[v]) continue; dfs(v, postorder, visited, graph); } postorder.push_back(current); } void sfd(int current, vector<int>& scc, const int id, vector< vector<int> >& hparg) { scc[current] = id; for (auto& v: hparg[current]) { if (scc[v]) continue; sfd(v, scc, id, hparg); } }
vector<int> kosaraju(vector< vector<int> >& graph) { vector<bool> visited(graph.size()); vector<int> postorder; postorder.reserve(graph.size()); function<void(int)> dfs = [&](int u) { if (visited[u]) return; for (auto& v: graph[u]) { visited[v] = true; dfs(v); } postorder.push_back(u); }; for (int u = 0; u < graph.size(); u++) dfs(u); vector< vector<int> > hparg(graph.size()); for (int u = 0; u < graph.size(); u++) { for (auto& v: graph[u]) hparg[v].push_back(u); } vector<int> scc(graph.size()); int sccCounter = 0; function<void(int)> sfd = [&](int u) { scc[u] = sccCounter; for (auto& v: hparg[u]) { if (scc[v]) continue; sfd(v); } }; reverse(postorder.begin(), postorder.end()); for (auto& u: postorder) { if (!scc[u]) ++sccCounter, sfd(u); } return scc; }
Thank you