java克鲁斯卡尔算法,最小生成树( 克鲁斯卡尔算法)

最小生成树( 克鲁斯卡尔算法)

/*

Name:

Copyright:

Author:

Date: 01-12-14 20:17

Description: 最小生成树( 克鲁斯卡尔算法)

关于并查集的算法,参见《一种简单而有趣的数据结构——并查集》http://blog.csdn.net/qiaoruozhuo/article/details/39674991

*/

#include#include#define MAXN 1000 //最大顶点数量

#define MAX 20000 //最大边数量

#define INFINITY 999999 //无穷大

int map[MAX][MAX] = {0};//邻接矩阵存储图信息

typedef struct EdgeNode{ //三元组边表集

int u, v; //弧尾和弧头

int w; //权值,对于非网图可以不需要

} EdgeNode;

void CreatGraph(EdgeNode *E, int m);//创建三元组边表集图

void CreatGraph_2(EdgeNode *E, int m, int n);//创建邻接矩阵图(随机图)

int Locate(EdgeNode *E, int n, int u, int v);//判断u,v是否是邻接点

void PrintGraph(EdgeNode *E, int m);//输出图

int cmp (const void *a , const void *b);//快排的配套函数

int FindFatherAndReducePath(int father[], int pos);//查找族长并压缩路径:找到族长后,将所途经的前辈结点均指向族长

int UnionBySize(int father[], int posI, int posJ);//按大小求并:将成员posI和posJ合并到同一个家族

void KRSL(EdgeNode *E, int m, int n);//克鲁斯卡尔算法求最小生成树

int main()

{

EdgeNode E[MAX];

int i, m, n;

printf("请输入顶点数量:");

scanf("%d", &n);

printf("\n请输入边数量:");

scanf("%d", &m);

CreatGraph_2(E, m, n);//创建三元组边表集图

PrintGraph(E, m);//输出图

qsort(E, m, sizeof(E[0]), cmp);//按照权值大小递增排序

PrintGraph(E, m);//输出图

KRSL(E, m, n);//克鲁斯卡尔算法求最小生成树

return 0;

}

void CreatGraph(EdgeNode *E, int m)//创建三元组边表集图

{

int i;

printf("\n请按照a b c格式输入边信息:\n");

for (i=0; i= %d\t", E[i].u, E[i].v, E[i].w);

}

printf("\n");

}

int cmp (const void *a , const void *b)//快排的配套函数

{

return (((EdgeNode *)a)->w > ((EdgeNode *)b)->w ? 1 : -1);

}

void KRSL(EdgeNode *E, int m, int n)//克鲁斯卡尔算法求最小生成树

{

int i, min, top = 1;

int father[MAXN] = {0};

EdgeNode minTree[MAXN] = {0};

for (i=0; i= %d\t", minTree[i].u, minTree[i].v, minTree[i].w);

min += minTree[i].w;

}

printf("\n最小生成树总长度(权值)为 %d\n", min);

}

int FindFatherAndReducePath(int father[], int pos)//查找族长并压缩路径:找到族长后,将所途经的前辈结点均指向族长

{

if (father[pos] <= 0)

return pos;

//若自己不是族长,则找到族长后,将所途经的结点均指向族长

return father[pos] = FindFatherAndReducePath(father, father[pos]);

}

int UnionBySize(int father[], int posI, int posJ)//按大小求并:将成员posI和posJ合并到同一个家族

{

//首先各自去寻找自己的族长

int fI = FindFatherAndReducePath(father, posI);

int fJ = FindFatherAndReducePath(father, posJ);

if (fI == fJ) //如果是同一个族长门下,不必合并,即合并失败

return 0;

if (father[fI] < father[fJ])

{//如果族长fI的实力比fJ强,即|fI|>|fJ|,则fI当族长,并修改father[fI]和father[fJ]

father[fI] += father[fJ];

father[fJ] = fI;

}

else //否则fJ当族长

{

father[fJ] += father[fI];

father[fI] = fJ;

}

return 1;

}

http://www.dengb.com/Javabc/921128.htmlwww.dengb.comtruehttp://www.dengb.com/Javabc/921128.htmlTechArticle最小生成树( 克鲁斯卡尔算法) /*Name: Copyright: Author: Date: 01-12-14 20:17Description: 最小生成树( 克鲁斯卡尔算法)关于并查集的算法,参见《...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值