Problem Description
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
Input
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M ( < 100 );随后的 N
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
Output
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
#include <stdio.h> #include <vector> #include <algorithm> using namespace std; struct Edge { int src, des, cost; bool operator<(const Edge& rhs) const { return cost < rhs.cost; } }; vector<Edge> edges; static const int V = 100; int parent[V]; void init(int n) { edges.clear(); for (int i = 0; i < n; ++i) parent[i] = -1; } int root(int &v) { int depth = 0; while (parent[v] != -1) { v = parent[v]; ++depth; } return depth; } bool merge(int& a, int& b) { int d1 = root(a); int d2 = root(b); if (a == b) return false; if (d1 < d2) parent[a] = b; else parent[b] = a; return true; } int Kruskal(int n) { sort (edges.begin(), edges.end()); int amount = 0; for (vector<Edge>::iterator it = edges.begin(); it != edges.end(); ++it) { if (merge(it->src, it->des)) // if merged, add the edge { amount += it->cost; if (--n == 1) return amount; } } return -1; // no enough edge, non-connected } int main() { while (1) { int n, m; scanf ("%d %d", &n, &m); if (n == 0) break; init (m); while (n--) { Edge edge; scanf ("%d %d %d", &edge.src, &edge.des, &edge.cost); --edge.des, --edge.src; edges.push_back(edge); } int amount = Kruskal(m); if (amount == -1) printf ("?/n"); else printf ("%d/n", amount); } return 0; }