- 题目大意
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。因此求出最少的成本为多少?
- 解题思路
最小生成树的问题,用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; }