码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1863 (最小生成树之Kruskal) 畅通工程

时间:2014-09-05 19:46:21      阅读:186      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   io   ar   for   art   

模板题,学习一下最小生成树的Kruskal算法

对于稀疏图来说

按所给的边的权值从小到大排序,如果该边不与已经选的边形成环就选择它

这里用并查集来实现

第i条边的端点放在u、v数组中,权值保存在w中

这里用的是间接排序,也就是排的是每条边的序号,放在rank数组中

 

bubuko.com,布布扣
 1 //#define LOCAL
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int maxn = 5000;
 8 int u[maxn], v[maxn], w[maxn], parent[maxn], rank[maxn];
 9 int m, n;
10 
11 bool cmp(const int i, const int j)
12 {
13     return (w[i] < w[j]);
14 }
15 
16 int GetParent(int a)
17 {
18     return parent[a] == a ? a : parent[a] = GetParent(parent[a]);
19 }
20 
21 int kruskal(void)
22 {
23     int cnt = 0, weight = 0;
24     for(int i = 0; i < m; ++i)
25     {
26         int edge = rank[i];
27         int x = GetParent(u[edge]);
28         int y = GetParent(v[edge]);
29         if(x != y)
30         {
31             weight += w[edge];
32             ++cnt;
33             parent[x] = y;
34         }
35     }
36     if(cnt < n - 1)    weight = 0;
37     return weight;
38 }
39 
40 int main(void)
41 {
42     #ifdef LOCAL
43         freopen("1863in.txt", "r", stdin);
44     #endif
45 
46 
47     while(scanf("%d%d", &m, &n) == 2 && m)
48     {
49         for(int i = 0; i < m; ++i)
50             scanf("%d%d%d", &u[i], &v[i], &w[i]);
51         for(int i = 0; i < n; ++i)    parent[i] = i;
52         for(int i = 0; i < m; ++i)    rank[i] = i;
53         sort(rank, rank + m, cmp);
54         int ans = kruskal();
55         if(ans)
56             printf("%d\n", ans);
57         else
58             printf("?\n");
59     }
60     return 0;
61 }
代码君

 

HDU 1863 (最小生成树之Kruskal) 畅通工程

标签:style   blog   http   color   os   io   ar   for   art   

原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/3958599.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!