[AcWing 859] Kruskal演算法求最小生成樹
阿新 • • 發佈:2022-05-07
複雜度 \(O(m*log(m))\)
點選檢視程式碼
#include<iostream> #include<algorithm> using namespace std; const int N = 1e5 + 10, M = 2 * N, INF = 0x3f3f3f3f; int n, m; int p[N]; int res, cnt; struct Edge { int a, b, w; bool operator< (const Edge & W) const { return w < W.w; } }edges[M]; int find(int x) { if (p[x] != x) p[x] = find(p[x]); return p[x]; } int Kruskal() { sort(edges, edges + m); for (int i = 1; i <= n; i ++) p[i] = i; for (int i = 0; i < m; i ++) { int a = edges[i].a, b = edges[i].b, w = edges[i].w; a = find(a), b = find(b); if (a != b) { p[a] = b; res += w; cnt ++; } } if (cnt < n - 1) return INF; else return res; } int main() { cin >> n >> m; for (int i = 0; i < m; i ++) { int a, b, w; cin >> a >> b >> w; edges[i] = {a, b, w}; } int t = Kruskal(); if (t == INF) puts("impossible"); else cout << res << endl; return 0; }
- Kruskal 思路:每次取出權值最小的邊,如果邊的兩個端點之間沒有連通,則把兩個端點放到同一個並查集當中;
- 要先對所有的邊進行排序,使用 sort 函式進行排序,在 struct 中對小於號進行過載;