最小生成树 HDU 1233 还是畅通工程
学会了并查集,kruskal算法就没有大问题了
先对边的权值排序, 再不断添加边(要保证不形成回路,用并查集),直到添加的边数为n-1时停止
这题WA几次,检查几次算法发现无问题,最后发现数组开少了,囧~
#include<iostream> #include <algorithm> #define MAX 105 using namespace std; struct Edge { int v; int w; int lenth; }; int parent[MAX]; int find(int ); void Union(int , int); bool cmp( Edge a, Edge b); int main() { int n, num, count,m; Edge edge[50*99+5]; int root_a, root_b; int total_len; while (cin >> n && n) { count = 1; total_len = 0; num = n*(n-1)/2; m = 0; memset(parent, -1, sizeof(int)*MAX); for (int i = 0; i < num; i++) scanf("%d%d%d", &edge[i].v, &edge[i].w, &edge[i].lenth); sort(edge, edge+num, cmp); //kruskal算法 while (count < n) { root_a = find(edge[m].v-1); root_b = find(edge[m].w-1); if (root_a != root_b) { Union(root_a, root_b); total_len += edge[m].lenth; count++; } m++; } cout << total_len << endl; } return 0; } bool cmp(Edge a, Edge b) { return a.lenth < b.lenth; } int find(int i) { int root, trail, lead; for (root = i; parent[root] >= 0; root = parent[root]); for (trail = i; trail != root; trail = lead) { lead = parent[trail]; parent[trail] = root; } return root; } void Union(int i , int j) { int temp = parent[i] + parent[j]; if (parent[i] > parent[j]) { parent[i] = j; parent[j] = temp; } else { parent[j] = i; parent[i] = temp; } }