上代码:如果有疑问的话,欢迎随时留言!
#include <stdio.h>
//闹了好长时间才闹好,如果有不懂的地方可以留言
//里面判断环的地方用到并查集
//并查集资料:http://dongxicheng.org/structure/union-find-set/
#define ENUM 15//边的数量
#define VNUM 9//顶点的数量
#define MV 0
typedef struct _tag_Edge //存储边的信息
{
int begin;
int end;
int weight;//权值
}Edge;
int father[VNUM]; //存储
int son[VNUM];
int Matvix[VNUM][VNUM]=
{//图
{0, 10, MV, MV, MV, 11, MV, MV, MV},
{10, 0, 18, MV, MV, MV, 16, MV, 12},
{MV, 18, 0, 22, MV, MV, MV, MV, 8},
{MV, MV, 22, 0, 20, MV, 24, 16, 21},
{MV, MV, MV, 20, 0, 26, MV, 7, MV},
{11, MV, MV, MV, 26, 0, 17, MV, MV},
{MV, 16, MV, 24, MV, 17, 0, 19, MV},
{MV, MV, MV, 16, 7, MV, 19, 0, MV},
{MV, 12, 8, 21, MV, MV, MV, MV, 0},
};
void swap(Edge array[], int i, int j)
{
Edge temp = array[i];
array[i] = array[j];
array[j] = temp;
}
void SelectionSort(Edge array[], int len) // O(n*n)
{
int i = 0;
int j = 0;
int k = -1;
for(i=0; i<len; i++)
{
k = i;
for(j=i; j<len; j++)
{
if( array[j].weight < array[k].weight )
{
k = j;
}
}
swap(array, i, k);
}
}
int unionsearch(int x) //查找根结点+路径压缩
{
if(x != father[x])
{//通过递归找到根结点,注意边最终的end为根结点
father[x] = unionsearch(father[x]);
}
//father[x]为x的父结点
return father[x];
}
int join(int x, int y) //合并
{
int root1, root2;
root1 = unionsearch(x);
root2 = unionsearch(y);
if(root1 == root2) //为环
return 0;
else
{ //root2为root1的父结点
father[root1] = root2;
son[root2] += son[root1];
}
return 1;
}
int main()
{
int i, j;//要使用的循环变量
int total = 0;//最后选出边的数量
int sum = 0;//最后总权值
int flag = 0;
int eNUM = ENUM-1;
Edge array[ENUM];//总共的边
for(i=0; i<VNUM; ++i) //初始化
{
father[i] = i;
son[i] = 1;
}
for(i=0; i<VNUM; i++)
{
for(j=0; j<VNUM; j++)
{
if((i<j) && (0 < Matvix[i][j]))
{//给边的结构体初始化
array[eNUM].begin = i;
array[eNUM].end = j;
array[eNUM--].weight= Matvix[i][j];
}
}
}
//排序 ,对边按照权值排序,从小到大
SelectionSort(array, ENUM);
for(i=0; i<ENUM; i++)
{
if(join(array[i].begin, array[i].end))
{//判断是否成环
total++; //边数加1
sum += array[i].weight; //记录权值之和
printf("%d -> %d weight:%d\n", array[i].begin, array[i].end, array[i].weight);
}
if(total == VNUM-1) //最小生成树条件:边数=顶点数-1
{
flag = 1;
break;
}
}
if(flag)
printf("%d\n", sum);
else
printf("error.\n");
return 0;
}