C - 暢通工程 (HDU - 1863)
阿新 • • 發佈:2018-02-15
暢通工程 通過 n) 題目 評估 生成樹 class break namespace
- 題目大意
省政府“暢通工程”的目標是使全省任何兩個村莊間都可以實現公路交通(但不一定有直接的公路相連,只要能間接通過公路可達即可)。經過調查評估,得到的統計表中列出了有可能建設公路的若幹條道路的成本。因此求出最少的成本為多少?
- 解題思路
最小生成樹的問題,用kruskal算法,kruskal算法是一種貪心策略,每次放長度(本題可以看做是建路的成本)最小的邊,如果兩個點屬於同一個集合就不放,否則會構成環,每放一個點我們記錄一次,最後把所有點都連通了就結束算法。
- 代碼
#include<iostream> #include<algorithm> using namespace std; const int MAX = 1e5 + 50; int fa[MAX]; struct Edge { int u, v, w; bool operator<(const Edge &rhs)const { return w < rhs.w; } }e[MAX]; void init(int n) { for (int i = 1; i <= n; i++) fa[i] = i; } int find(int x) { if (x == fa[x]) return x; else { return fa[x] = find(fa[x]); } } bool Union(int x, int y) { int fx = find(x), fy = find(y); if (fx == fy) return false; else { fa[fx] = fy; return true; } } int kruskal(int n, int m) { sort(e, e + m); init(n); int sum = 0; for (int i = 1; i <= m; i++) { int u = e[i].u, v = e[i].v, w = e[i].w; if (Union(u, v)) { sum += w; } } return sum; } int main() { int n,m,tmp,sum; while (cin >> n >> m) { if (n == 0) break; for (int i = 1; i <= n; i++) cin >> e[i].u >> e[i].v >> e[i].w; tmp = kruskal(m, n); sum = 0; for (int i = 1; i <= m; i++) { if (fa[i] == i) sum++; } if (sum > 1) cout << "?" << endl; else { cout << tmp << endl; } } return 0; }
C - 暢通工程 (HDU - 1863)