题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1233
思路
最小生成树问题,使用Prime算法或者Kruskal算法解决。
代码
Prime算法:
1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int INF = 0xfffffff; 7 const int N = 100 + 10; 8 int map[N][N]; 9 int dist[N]; //存储从起点到其余各点的距离,不断更新 10 int n; 11 12 void prime() 13 { 14 int min_edge, min_node; 15 for (int i = 1;i <= n;i++) 16 dist[i] = INF; 17 int ans = 0; 18 int now = 1; 19 for (int i = 1;i < n;i++) 20 { 21 dist[now] = -1; 22 min_edge = INF; 23 for (int j = 1;j <= n;j++) 24 { 25 if (j != now && dist[j] >= 0) 26 { 27 if (map[now][j]>0) 28 dist[j] = min(dist[j], map[now][j]); 29 if (dist[j] < min_edge) 30 { 31 min_edge = dist[j]; //min_edge存储与当前结点相连的最短的边 32 min_node = j; 33 } 34 } 35 } 36 ans += min_edge; //ans存储最小生成树的长度 37 now = min_node; 38 } 39 printf("%d ", ans); 40 } 41 42 int main() 43 { 44 //freopen("hdoj1233.txt", "r", stdin); 45 while (scanf("%d", &n) == 1 && n) 46 { 47 memset(map, 0, sizeof(map)); 48 int a, b, c; 49 int nums = n*(n - 1) / 2; 50 for (int i = 0; i < nums; i++) 51 { 52 scanf("%d%d%d", &a, &b, &c); 53 map[a][b] = c; 54 map[b][a] = c; 55 } 56 prime(); 57 } 58 return 0; 59 }
Kruskal算法:
1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio> 4 #include <vector> 5 using namespace std; 6 7 struct Edge 8 { 9 int a, b, dist; 10 11 Edge() {} 12 Edge(int a, int b, int d) :a(a), b(b), dist(d) {} 13 bool operator < (Edge edge) //按边长从短到长排序 14 { 15 return dist < edge.dist; 16 } 17 }; 18 19 const int N = 100 + 10; 20 int p[N]; //并查集使用 21 vector<Edge> v; 22 int n; 23 24 int find_root(int x) 25 { 26 if (p[x] == -1) 27 return x; 28 else return find_root(p[x]); 29 } 30 31 void kruskal() 32 { 33 memset(p, -1, sizeof(p)); 34 sort(v.begin(), v.end()); 35 int ans = 0; 36 for (int i = 0; i < v.size(); i++) 37 { 38 int ra = find_root(v[i].a); 39 int rb = find_root(v[i].b); 40 if (ra != rb) 41 { 42 ans += v[i].dist; 43 p[ra] = rb; 44 } 45 } 46 printf("%d ", ans); 47 } 48 49 int main() 50 { 51 //freopen("hdoj1233.txt", "r", stdin); 52 while (scanf("%d", &n) == 1 && n) 53 { 54 int a, b, d; 55 int nums = n*(n - 1) / 2; 56 v.clear(); 57 for (int i = 0; i < nums; i++) 58 { 59 scanf("%d%d%d", &a, &b, &d); 60 v.push_back(Edge(a, b, d)); 61 } 62 kruskal(); 63 } 64 }