标签:style blog http color os io ar for art
模板题,学习一下最小生成树的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 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 }
标签:style blog http color os io ar for art
原文地址:http://www.cnblogs.com/AOQNRMGYXLMV/p/3958599.html