最小生成树-Prim算法

题目链接http://acm.whu.edu.cn/learn/problem/detail?problem_id=1038

这是woj里面的一道题目,已知了所有点的坐标,求一条长l的线是否可以将所有的点连接起来。
其主要思路就是采用最小生成树。我们采用Prim算法构造最小生成树。
这道题目中首先利用一个数组来表示节点之间的距离,其中同一节点用无穷大来进行表示。然后调用Prim算法来构造最小生成树

下面看具体代码以及注释,来了解Prim算法

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define MAXV 103
#define MAXCOST 0x7fffffff
float quan[MAXV][MAXV];  //存放节点之间的权值
struct{
    int x;
    int y;
}jiedian[MAXV];  //存放每个节点的横纵坐标 

float Prim(float graph[][MAXV],int n){
    float lowcost[MAXV];   //表示以i为终点的权值。当lowcost[i]=0时,表示已经加入最小生成树
    int mst[MAXV];   //存放lowcost[i]对应的节点
    //首先假设第0个节点已经处于最小生成树里面
    lowcost[0]=0;
    mst[0]=0;
    //则lowcost里面存放从第一个节点到最后一个节点到第0个节点的距离
    for(int i=1;i<n;i++){
        lowcost[i]=quan[0][i];
        mst[i]=1;
    } 
    float sum=0;
    for(int i=1;i<n;i++){
        //从第一个节点开始遍历
        float min=MAXCOST;
        int minid=0;
        for(int j=1;j<n;j++){ //求与该节点最近的点 
            if(lowcost[j]<min && lowcost[i]!=0){
                min=lowcost[i];
                mst[i]=j;       
            } 
        }
        sum+=min;
        //更新lowcost
        lowcost[minid]=0;
        for(int j=1;j<n;j++){
            if(lowcost[j]>graph[minid][j]){
                lowcost[j]=graph[minid][j];
                mst[j]=minid;
            }
        } 

    }
    return sum;

} 
int main(){
    int n,l;
    while(scanf("%d",&n) && n!=0){
        scanf("%d",&l);
        for(int i=0;i<n;i++){
            scanf("%d %d",&jiedian[i].x,&jiedian[i].y);
        }
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
            float xx=pow((float)(jiedian[i].x-jiedian[j].x),2)+pow((float)(jiedian[i].y-jiedian[j].y),2); //计算节点之间距离 
            quan[i][j]=sqrt(xx);
            quan[i][i]=MAXCOST;   //相同节点之间距离为无穷大 
            }
        }
        float cost=Prim(quan,n);   //求出最小生成树 
        if(cost<=l) printf("Success!\n");
        else printf("Poor magicpig!\n");
    }
    return 0;
} 

总的来说Prim算法主要用到三个数组,其中有一个表示节点直接的权值,一个数组表示目前最小生成树到未加入节点的最短距离,另外一个数组对应这些未加入数组离已加入的节点最近的节点标记。
Prim算法的流程主要是初始化,判断最近节点,更新剩余节点三个步骤一般来说,代码片段中的Prim算法可以直接进行调用。

之后会不断补充有关最小生成树的相关OJ题目来进一步巩固最小生成树

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值