对图论的理解prm算法,最小生成树,边长,poj2395

本文深入探讨Prim算法,一种用于解决最小生成树问题的经典算法。通过实例讲解Prim算法的具体实现过程,包括初始化变量、选择最小权重边以及更新顶点状态等关键步骤。同时,提供完整的代码示例,帮助读者理解和掌握Prim算法的应用。

截至到目前为止,对图论已经看到六种算法了,第一种就是自己很理解的并查集算法,上面的题中自然有提到,第二种便是dijkstra算法,当然上面题中依然有提到的,第三种便是floyd算法,至于这个经典算法,当然也要会用点的,第四种便是接下来要说的prim算法,至于第五种的拓扑排序和krustkal算法,目前还没用过,这里暂不提;

 

题目链接:                             http://poj.org/problem?id=2395

 

这一题的大致就是从一个庄园到另一个庄园,在每个庄园都可以装水,求要经过所有庄园要求所带的水尽量少,求在这种尽量小的情况下拿水最多的一次,并且所有庄园都可以由1号庄园到达;

这里用了prim算法,主要代码如下:

int map[1000][1000];

int flag[1000];

int count[1000];

int x,max,min,k;

#define inf Oxffffffff

for(i=1,i<=n;i++) 

{

flag[i]=0;

count[i]=map[x][i];l////x为起始庄园;

}

flag[x]=1;

count[x]=0;

for(i=1;i<=n;i++)

{

min=inf;

for(j=1;j<=n;j++)

{

if(flag==0&&count[i]<min)

{

min=count[i];

k=j;

}

}

flag[k]=1;

for(j=1;j<=n;j++)

{

if(flag[j]==0&&count[j]>map[k][j])///由于prim算法球的只是最短边,所以这里便是求最短边得地方

count[j]=map[k][j];          ////也就是从x到 j边如果比从k到j大,便用从k到j边,因为前提从x到j目前是剩下的最小的边

}                                    ///这样一连,图是联通的

max=0;

for(j=1;j<=n;j++)

if(count[j]>max)

max=count[j];

return max:

}

此题代码如下:
View Code
#include<stdio.h>
#include<string.h>
#include<cstdio>
#include<cstring>
#define inf 0x7fffffff
int map[3005][3005];
int count[3005];
int flag[3005];
int n;
int prm()
{
    int i,j,k,min,max=0;
    for(i=1;i<=n;i++)
    {
        flag[i]=0;
        count[i]=map[1][i];        
    }
    flag[1]=1;
    count[1]=0;
    for(i=1;i<=n;i++)
    {
        min=inf;
        for(j=1;j<=n;j++)
        {
            if(flag[j]==0&&count[j]<min)
            {
                min=count[j];
                k=j;
            }
        }
        /*if(count[k]>max)
            max=count[k];*/
        flag[k]=1;///
        for(j=1;j<=n;j++)
            if(flag[j]==0&&count[j]>map[k][j])
                count[j]=map[k][j];
    }
    for(i=2;i<=n;i++)
        if(count[i]>max)
            max=count[i];
        return max;    
}

int main()
{
    int m,i,j,x,y,len;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)    
                map[i][j]=inf;    
    for(i=0;i<m;i++)
    {
        scanf("%d%d%d",&x,&y,&len);
        if(map[x][y]>len)
            map[x][y]=len;
        if(map[y][x]>len)
            map[y][x]=len;
    }
    len=prm();
    printf("%d\n",len);
    return 0;
}

 

  

 

转载于:https://www.cnblogs.com/world-ding/articles/2137718.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值