/**********************************************************************\ 功 能: 利用Kruscal算法求 " 无向图 " 的最小生成树 输入说明: 首先输入图的顶点数 n 边数 m 接着下一行每行输入每一条边 包括起点,终点,权值 (顶点从 1 开始编号) 输出说明: 输出最小生成树的各边,包括起点,终点,权值,最后输出总 的权值。 调试实例: 输入文件:( 用管道调试 ) 6 10 1 2 4 1 3 8 1 4 5 1 6 7 4 3 2 4 5 11 4 6 3 6 5 2 3 5 9 2 3 6 输出结果: The Graphy's smallest tree's sides as follow: start end 1 2 4 1 4 5 4 3 2 4 6 3 6 5 2 Total is :16 语 言: 非标准 C 编译环境:VC ++ 6.0 Author : 江南孤峰 Time :2006--11--1 \**********************************************************************/ #include <stdio.h>#include <process.h>#include <stdlib.h>#include <limits.h>#include <malloc.h>#include <string.h> typedef struct Side{ //边集包括 起点,终点,权值 int StartPoint; int EndPoint; int Value; struct Side *next;}DefSide; int main(){ int n,m,s,e,v,np,i,j; int *presult; //结果中用于存储节点编号的数组 int *meter;//邻接矩阵 DefSide *temp,*sides; //用于存最小生成树的边信息 scanf("%d%d",&n,&m); presult = (int *)malloc(sizeof(int) * n + 2); meter = (int *)malloc(sizeof(int) * n * n + 2); memset(meter,0,n * n * sizeof(int) + 2); for(j = i = 0; i < m; j = 0,i ++){ scanf("%d %d %d",&s,&e,&v); *(meter + (s-1)*n + e-1) = v; *(meter + (e-1)*n + s-1) = v; /* 注意如果是求有向图的最小生成树,只需将该付值语句注释掉 */ } temp=sides=(DefSide *)malloc(sizeof(DefSide)); for(np = presult[0] = 0; np < n; np ++){ //检查结果节点集是否已满 temp -> Value = INT_MAX; //初始化边链表节点的值 for(i = 0; i <= np; i ++){ //结果节点集里的节点做为起点 for(j = 0; j < n; j ++){ //寻找终点 for(s = 0; s <= np; s ++){ //如果该终点已在结果节点集中存在则放弃该终点 if(j == presult[s]){ s = -1; break; } } if(s == -1) //该终点不符合要求,选择下一个点 continue; //选择一条最短的边,存入结果的边链表中 if( *(meter + presult[i]*n + j) && *(meter + presult[i]*n + j) < temp->Value ){ temp->Value = *(meter + presult[i]*n + j); temp->StartPoint = presult[i]; temp->EndPoint = j; } } } presult[np+1] = temp->EndPoint; //更新结果节点集 temp -> next = (DefSide *)malloc(sizeof(DefSide)); //分配新的边链表节点 temp = temp -> next; } temp -> next = NULL; printf("The Graphy\'s smallest tree\'s sides as follow:\n"); printf("%-8s%-8s%-8s\n","start","end","Value"); for(v = i = 0,temp = sides,n --; i < n; i ++){//输出组成该图最小生成树的边,包括边的起点 ,终点,值 printf("%-8d%-8d%-8d\n",temp->StartPoint+1,temp->EndPoint+1,temp->Value); v += temp -> Value; sides = temp; temp = temp -> next; free(sides); } printf("Total value is :%d\n",v); free(temp); return EXIT_SUCCESS;}

评论