题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233
思路分析:该问题为最小生成树问题,使用kruskal算法或者prim算法即可解决;
代码如下:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int MAX_N = 5000 + 10; int u[MAX_N], v[MAX_N], w[MAX_N]; int p[MAX_N], r[MAX_N]; inline int cmp(const int i, const int j) { return w[i] < w[j]; } int Find(int a) { if (p[a] == a) return a; else return p[a] = Find(p[a]); } int Union(int a, int b) { int p_a = Find(a); int p_b = Find(b); if (p_a == p_b) return -1; if (p_a > p_b) p[p_b] = p_a; else p[p_a] = p_b; return 1; } inline int Kruskal(int road_num) { int ans = 0; for (int i = 0; i <= road_num; ++i) p[i] = i; for (int i = 0; i < road_num; ++i) r[i] = i; sort(r, r + road_num, cmp); for (int i = 0; i < road_num; ++i) { int e = r[i]; int x = Find(u[e]); int y = Find(v[e]); if (x != y) { ans += w[e]; Union(x, y); } } return ans; } int main() { int ver_num; int ver_1, ver_2, len; while (scanf("%d", &ver_num) != EOF && ver_num) { int road_num = ver_num * (ver_num - 1) / 2; for (int i = 0; i < road_num; ++i) { scanf("%d %d %d", &ver_1, &ver_2, &len); u[i] = ver_1; v[i] = ver_2; w[i] = len; } int ans = Kruskal(road_num); printf("%d ", ans); } return 0; }