布线问题(普利姆算法)

普里姆(Prim)算法

  1.基本思想:设G=(V, E)是具有n个顶点的连通网,T=(U, TE)是G的最小生成树, T的初始状态为U={u0}(u0∈V),TE={},重复执行下述操作:在所有u∈U,v∈V-U的边中找一条代价最小的边(u, v)并入集合TE,同时v并入U,直至U=V。即:

(1)从连通网络 G = { V, E }中的某一顶点 u0 出发,选择与它关联的具有最小权值的边(u0, v),将其顶点加入到生成树的顶点集合U中。

  (2)以后每一步从一个顶点在U中,而另一个顶点不在U中的各条边中选择权值最小的边(u, v),把它的顶点加入到集合U中。如此继续下去,直到网络中的所有顶点都加入到生成树顶点集合U中为止。

示例:

昨晚上学长讲了最小生成树中的普利姆算法,不过没有将代码实现,今天纠结了一天,嘿嘿,终于搞明白了一点,这个题是一个赤裸裸的最小生成树问题,也许会有很多错误,希望有人能帮我找出.

题目:布线问题

原题地址:请猛击

AC代码

时间:32ms 内存:1212

#include<stdio.h> #include<string.h> int m[502][502],flag[502]; int prim(int n) //用普利姆算法找最小生成树函数 { int i,j,sum=0,min,temp; i=1; for(int k=1;k<n;k++) { flag[i]=1; //i为研究对象 flag为标记该点是否研究过,确定最小分支 min=999999; for(j=1;j<=n;j++) //更新各个点对应的最小值 { if(m[0][j]==0) m[0][j]=m[i][j]; else if(!flag[j]&&m[0][j]>m[i][j]) m[0][j]=m[i][j]; } for(j=2;j<=n;j++) { if(!flag[j] &&min>m[0][j]) //确定该研究对象中的最小分支 { min=m[0][j]; temp=j; } } i=temp; sum+=min; } return sum; } int main() { int n,i,j,k,l,p,weight; scanf("%d",&n); while(n--) { int min=9999999; memset(m,0,sizeof(m)); memset(flag,0,sizeof(flag)); scanf("%d%d",&k,&l); for(p=1;p<=l;p++) { scanf("%d%d%d",&i,&j,&weight); m[i][j]=weight; //将各个点添加到二维数组中 m[j][i]=weight; } for(p=1;p<=k;p++) { scanf("%d",&weight); //找出最少费用 if(min>weight) min=weight; } printf("%d\n",prim(k)+min); } return 0; }


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值