KrusKal求最小生成树
来源:互联网 发布:手机绘制平面图软件 编辑:程序博客网 时间:2024/04/28 04:27
这个算法的主要难点是:怎么避免连通图成环,可以用并查集算法
参考:http://blog.csdn.net/dellaserss/article/details/7724401/
图例:
代码:
#include<stdio.h>#include<stdlib.h>/*主要采用并查集来判断是否成环,加入了路径压缩*/#include <malloc.h>#include <string.h>#define MAX 20#define nLENGTH(a) (sizeof(a)/sizeof(a[0]))#define eLENGTH(a) ( sizeof(a) / sizeof(char) )/ ( sizeof(a[0]) / sizeof(char) )//邻接矩阵typedef struct _graph{ char vexs[MAX]; // 顶点集合 int vexnum; // 顶点数 int edgnum; // 边数}Graph, *PGraph; // 边的结构体typedef struct _EdgeData{ char start; // 边的起点 char end; // 边的终点 int weight; // 边的权重}EData;//指向节点的位置int point_node(PGraph g,char c){for(int i=0;i<g->vexnum;i++){if(g->vexs[i]==c){return i;}}return -1;}//对边按权值大小排序void Sort_edg(EData edg[],int e){int i,j; for (i=0; i<e; i++) { for (j=i+1; j<e; j++) { if (edg[i].weight > edg[j].weight) { // 交换"第i条边"和"第j条边" EData tmp = edg[i]; edg[i] = edg[j]; edg[j] = tmp; } } }for(j=0;j<e;j++){printf("%c--%c\t%d",edg[j].start,edg[j].end,edg[j].weight);printf("\n");}}/*并查集的主要思路以下:*///-------------------------------------------------------------------------------//找到根顶点 int FindRoot(int a[],int p){int r=p;while(a[r]!=r)r=a[r];//路径压缩int x=p,j;while(x!=r){j=a[x]; //j 保存 p 的父顶点a[j]=r; //把 终端顶点 r 赋给 p的父顶点x=j; //把j值赋给x,不断循环,把父级的父级 r 一次一次赋给 x ,直到x与 r相等}return r;}//--------------------------------------------------------------------------------void KrusKalTree(int b[][3],char a[],int L,int e){int rand=0;PGraph g; //矩阵EData edg[MAX];//保存边数组int ch[MAX]={0,1,2,3,4,5,6};//并查集用 EData rets[MAX]; //用来存放选择好的边g=(PGraph)malloc(sizeof(Graph));//memset()第一个参数 是地址,第二个参数是开辟空间的初始值,第三个参数是开辟空间的大小printf("顶点个数:\n");//顶点数g->vexnum=L;printf("%d\n",g->vexnum);printf("边个数:\n");//边数g->edgnum=e;printf("%d\n",g->edgnum);//初始化顶点for(int j=0;j<g->vexnum;j++){g->vexs[j]=a[j];}//得到边的数组for(int i=0;i<e;i++){edg[i].start=char(b[i][0]);edg[i].end=char(b[i][1]);edg[i].weight=b[i][2];}//对边进行排序Sort_edg(edg,e);//进行并查集求解for(int k=0; k< e ; k++){int p1,p2,m,n;p1=point_node(g,edg[k].start);p2=point_node(g,edg[k].end);//找他们的根顶点m=FindRoot(ch,p1);n=FindRoot(ch,p2);if(m!=n){ch[m]=n;rets[rand++]=edg[k];}}printf("得到的最小生成树:\n");//打印已经得到的最小生成树的边for(j=0;j<rand;j++){printf("%c--%c\t%d",rets[j].start,rets[j].end,rets[j].weight);printf("\n");}//通过循环,可以看出,压缩路径起了作用,不用通过循环即可,找到终端顶点for(j=0;j<rand;j++){printf("%d\t",ch[i]);}}//测试int main(){int i,j;PGraph gp;//测试用例char a[]={'A', 'B', 'C', 'D', 'E', 'F', 'G'};int b[][3]={ {'A', 'B',12}, {'A', 'F',16}, {'A', 'G',14}, {'B', 'F',7}, {'B', 'C',10}, {'C', 'F',6}, {'C', 'E',5},{'C', 'D',3},{'D', 'E',4},{'E', 'F',2},{'E', 'G',8},{'F', 'G',9}}; //测试用例int n=nLENGTH(a);int e=eLENGTH(b);KrusKalTree(b,a,n,e);return 0;}
1 0
- KrusKal求最小生成树
- HDU-1233(kruskal求最小生成树)
- hdu1863(kruskal求最小生成树)
- hdu1879(kruskal求最小生成树)
- Kruskal算法求最小生成树
- ZOJ1203 kruskal求最小生成树
- POJ1251 || ZOJ1406 kruskal求最小生成树
- hdu 1233 Kruskal求最小生成树
- Kruskal 算法 求最小生成树
- 24.kruskal算法 求 最小生成树
- poj2485 Highways(kruskal求最小生成树)
- Kruskal算法(求最小生成树)
- Kruskal算法求最小生成树
- Kruskal 算法求最小生成树
- uva1395 Kruskal算法求最小生成树
- hdu1102 kruskal算法求最小生成树
- Kruskal算法求最小生成树
- Kruskal算法求MST(最小生成树)
- TS流压縮音频的自动增益控制方法
- fprintf与fwrite的区别
- 蓝桥杯 -算法训练 区间k大数查询 java算法
- Ubuntu Docker 安装
- The journey of a packet through the linux 2.4network stack
- KrusKal求最小生成树
- EditText所遇到的问题
- MAT的使用
- 调试利器——Stetho
- 使用TAP网卡-加速你的虚拟机到host的访问
- 第三章—Cortex-A8处理器编程(上)
- codeforces - 735B - Urbanization(贪心)
- ThreadLocal使用
- sqlite数据库