正文

最小生成树2007-03-20 09:27:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/lingdlz/24112.html

分享到:

/**********************************************************************\
 功    能:  利用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;
}

阅读(4550) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册