最小生成树的prim算法:pku2485Highways、PKU1258Agri-Net解题报告

对于图,其生成树中的边也带权,将生成树各边的权值总和称为生成树的权,并将权值最小的生成树称为最小生成树(Minimun Spanning Tree),简称为MST。有两种非常典型的算法:Prim算法和kruskal算法,这两种算法都采用了贪心策略。
Prim算法的基本思想是:
(1) 在图G=(V,E)(V表示顶点,E表示边)中,从集合V中任取一个顶点(例如取顶点v0)放入集合U中,这时U={v0},集合T(E)为空。
(2) 从v0出发寻找与U中顶点相邻(另一顶点在V中)权值最小的边的另一顶点v1,并使v1加入U。即U={v0,v1},同时将该边加入集合T(E)中。
(3) 重复(2),直到U = V为止。
这时T(E)中有n-1条边,T=(U,T(E))就是一棵最小生成树。
在本例中,数组origin存放原始数据,max_distance存放矩阵中的最大值,
result 存放最小生成树的最大边,opt存放节点和最小生成树之间的最小距
离, flag判断是否已经加入到最小生成树中,首先将1号顶点加入最小生成树
中,flag[1]为true,其他为false,opt[i]的值为origin[1][i]的值,然后选
择不在最小生成树中的最小边i,然后加入到最小生成树中,另外更新

opt[i],flag[i]。如此反复,直到取到v-1条边为止。

AC代码:

//采用prim算法求最小生成树
#include <stdio.h>
int main(void)
{
    //数组origin存放原始数据,max_distance存放矩阵中的最大值,result存放最小生成树的最大边
    //opt存放节点和最小生成树之间的最小距离
    int n,i,j,count,origin[500][500],opt[500],max_distance=0,min,vertex,result=0;
    //flag判断是否已经加入到最小生成树中
    bool flag[500];
    scanf("%d",&count);
    while(count-->0)
    {
        
        scanf("%d",&n);
        result=0; //result清零
//输入origin,并记录矩阵中的最大值
        for(i=0;i<n;i++)
        {
            for(j=0;j<n;j++)
            {
                scanf("%d",&origin[i][j]);
                if(origin[i][j]>max_distance)
                    max_distance=origin[i][j];
            }
        }
        //0号节点加入到生成树中,当前最小距离为origin[0][i]的值       
        for(i=0;i<n;i++)
            opt[i]=origin[0][i];
//flag初始化,0节点先加入生成树中,为true,其他为false
        flag[0]=true;
        for(i=1;i<n;i++)
            flag[i]=false;
        for(i=1;i<n;i++)   //循环n-1次,获得n-1条边
        {
            min=max_distance+1;
            for(j=0;j<n;j++)
            {
                if(!flag[j]&&min>opt[j])
                {
      //获得不在生成树中的最小的边,记录节点
                    min=opt[j];
                    vertex=j;
                }
            }
     //更新result和该节点的flag 
            if(result<min)
                result=min;
            flag[vertex]=true;
     //修改每个节点的opt 
            for(j=0;j<n;j++)
            {
                if(!flag[j])
                    opt[j]=origin[j][vertex]>opt[j]?opt[j]:origin[j][vertex];
            }
        }
        printf("%d/n",result);
    }
    return 1;
}

PKU1258Agri-Net和2485基本上是一模一样,把result改为result+=min就过了,就不多说了。

相似类型的题目还有:http://acm.pku.edu.cn/JudgeOnline/problem?id=2395 (注意有重边,所以每次输入一条边都要判断它是否是这两个点的最小边。。)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值