克鲁斯卡尔Kruskal
2016-06-10 14:22
260 查看
寻找直接或间接连通所有城市的,最小费用的道路集合的问题,就是寻找最小生成树的问题.
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #define MAX 100 /* 定义边(x,y),权为w */ typedef struct { int x, y; int w; }edge; edge e[MAX]; /* rank[x]表示x的秩 */ int rank[MAX]; /* father[x]表示x的父节点 */ int father[MAX]; int sum; //typedef int (*cmptr)(const int a, const int b); int cmp(const void*a,const void*b) { return (*(edge*)a).w>(*(edge*)b).w?1:-1; } /*堆排序*/ /* 初始化集合 */ void Make_Set(int x) { father[x] = x; rank[x] = 0; } /* 查找x元素所在的集合,回溯时压缩路径 */ int Find_Set(int x) { if (x != father[x]) { father[x] = Find_Set(father[x]); } return father[x]; } /* 合并x,y所在的集合 */ void Union(int x, int y, int w) { if (x == y) return; /* 将秩较小的树连接到秩较大的树后 */ if (rank[x] > rank[y]) { father[y] = x; } else { if (rank[x] == rank[y]) { rank[y]++; } father[x] = y; } sum += w; } /* 主函数 */ int main() { int i, n; int x, y; char chx, chy; for(i=1;i<=26;i++) Make_Set(i); scanf("%d", &n); getchar(); for (i = 1; i <=n; i++) { scanf("%c%c", &chx, &chy); getchar(); scanf("%d",&e[i].w); getchar(); e[i].x = chx - 'a'+1; e[i].y = chy - 'a'+1; } qsort(e,n,sizeof(e[0]),cmp); sum = 0; for (i = 1; i <=n; i++) { x = Find_Set(e[i].x); y = Find_Set(e[i].y); if (x != y) { printf("%c - %c : %d\n",e[i].x + 'a'-1, e[i].y + 'a'-1, e[i].w); Union(x, y, e[i].w); } } printf("Total:%d\n", sum); return 0; }
相关文章推荐
- Kruskal 最小生成树
- 最小生成树
- 图的最小生成树学习笔记
- BestWiring——Kruskal算法&并查集
- 杭电1233
- 最小生成树之克鲁斯卡尔算法
- Sicily 1090. Highways
- poj 宝昌县长要修路(Kruskal最小生成树)
- hdu 1102 kruskal Constructing Roads
- hud 1233 还是畅通工程( kruskal和prim两种方法)
- hdu 1875 畅通工程再续 (kruskal算法+并查集)
- HDU 1598 find the most comfortable road
- 最小生成树
- 基本图算法时间复杂度
- 最小生成树之kruskal算法
- kruskal最小生成树
- Introduce to algorithm--------pseudo code to C/C++ code (chapter 23)
- 最小生成树Kruskal
- HLGOJ 1101 Bombs of HRBUST(kruskal)
- HLGOJ 1133 MST(kruskal)