prim算法

来源:互联网 发布:什么是网络语言 编辑:程序博客网 时间:2024/06/05 20:04

prime算法用于解决wikioi 1003题

//1003 电话连线//http://www.wikioi.com/problem/1003//********************************************************************mst[]用父节点标注法,即mst[j]=i表示j的父亲节点是i ********************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#define MAX 110#define MAXC 0x7fffffffint n,m;int map[MAX][MAX];//邻接矩阵 //mst[i]记录对应mincost[i]的起点,当mst[i]=0时表示起点i加入生成树int mst[MAX];//mincost[i]记录以i为终点的边的最小权值,当mincost[i]=0时表示终点i加入生成树int mincost[MAX],edge[MAX][2]={0},flag[MAX]={0};int prim(){  int i,j,min,minid,sum=0;    for(i=0;i<=n;i++)mincost[i]=-1;  //默认选择1号节点加入生成树,从2号节点开始初始化  for(i=2;i<=n;i++){    //短距离初始化为其他节点到1号节点的距离    mincost[i]=map[1][i];    //短距离初始化为其他节点到1号节点的距离    mst[i]=1;  }  //标记1号节点加入生成树 mst[1]=0;for(i=2;i<=n;i++){min = MAXC;minid = 0; //找满足条件的最小权值边的节点minid for(j= 2;j<=n;j++){// 边权值较小且不在生成树中 if(mincost[j]<min && mincost[j] != -1){min = mincost[j];minid = j;}}//累加权值sum+=min; //标记节点minid加入生成树mincost[minid] = -1; if(min!=0){edge[m][0]=mst[minid];edge[m][1]=minid;m++;}// 更新当前节点minid到其他节点的权值for(j=2;j<=n;j++){/* 发现更小的权值 */if(map[minid][j]<mincost[j]){/* 更新权值信息 */mincost[j]=map[minid][j]; /* 更新最小权值边的起点 */mst[j] = minid;}}}/* 返回最小权值和 */return sum;}int main(){  int i,j,ans;  scanf("%d",&n);  for(i=1;i<=n;i++)    for(j=1;j<=n;j++)map[i][j]=MAXC;    for(i=1;i<=n;i++)    for(j=1;j<=n;j++)      scanf("%d",&map[i][j]);  ans=prim();  printf("%d\n",m);  for(i=0;i<m;i++)        if(edge[i][0]>edge[i][1])printf("%d %d\n",edge[i][1],edge[i][0]);    else printf("%d %d\n",edge[i][0],edge[i][1]);  printf("%d\n",ans);  return 0;}


原创粉丝点击