首页 > 代码库 > HDU 1863 (最小生成树之Kruskal) 畅通工程
HDU 1863 (最小生成树之Kruskal) 畅通工程
模板题,学习一下最小生成树的Kruskal算法
对于稀疏图来说
按所给的边的权值从小到大排序,如果该边不与已经选的边形成环就选择它
这里用并查集来实现
第i条边的端点放在u、v数组中,权值保存在w中
这里用的是间接排序,也就是排的是每条边的序号,放在rank数组中
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 LOCAL43 freopen("1863in.txt", "r", stdin);44 #endif45 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 else58 printf("?\n");59 }60 return 0;61 }
HDU 1863 (最小生成树之Kruskal) 畅通工程
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。