最小生成树-Prim算法

来源:互联网 发布:网络教育院校 编辑:程序博客网 时间:2024/05/18 00:54

题目链接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 0x7ffffffffloat 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 0