考研最小生成树

void prim(Mgraph g,int v0,int &sum)//Mgraph 是连接矩阵,v是从哪个点开始,sum保存最小生成树的值。
{
    int lowcost[maxSize],vest[maxSize],v;//lowcost数组保存最小花费,vest保存是否用过 1是用过m,0是未到达
    sum=0;
    v=v0;
    for(int i=0;i<g.n;i++)
    {
        lowcost[i]=g.edge[v][i];
        vest[i]=0;
    }
    vest[v]=1;
    
    for(int i=0;i<g.n-1;i++)//已经一个点了,还需要n-1个点
    {
        int min=Inf;
        int k=-1;//加进去哪个点。
        for(int j=0;j<=g.n-1;j++)
        {
            if(vest[j]==0&&min>lowcost[j])
            {
                k=j;
                min=lowcost[j];
            }
        }
        sum=sum+min;
        vest[k]=1;
        for(int j=0;j<=g.n-1;j++)
        {
            if(vest[j]==0&&lowcost[j]>g.edge[j][k])
                lowcost[j]=g.edge[j][k];
        }
    }
    
}

最小生成树

就是使n个点连通的所有边的权值最小的一个解

 

prim就是每次加进去一个点就更新路径。然后每次都加进去最短的路。

 

kruskal 就是我先不管 每次找这张图的最短边。如果这2条边已经联通了,就不加入,怎么判断联通呢——并查集

不会的可以看一下这个:https://blog.51cto.com/ahalei/2348145 看不会————立即推放弃考研。

开个玩笑,那就来一个有趣点的 https://blog.csdn.net/tingtingyuan/article/details/81697698  

 

typedef struct Road
{
    int a,b;
    int w;
}Road;
Road road[maxSize];
int father[maxSize];
int find_father(int n)
{
    while (n!=father[n]) {
        n=father[n];
    }
    return n;
}
void kruskal(Mgargh g,int &sum ,Road road[])
{
    sum=0;
    int N=g.n;
    int E=g.e;
    sort(road,road+E);
    for(int i=0;i<N;i++)
        father[i]=i;//并查集的初始化;
    for(int i=0;i<E;i++)
    {
        int a=find_father(road[i].a);
        int b=find_father(road[i].b);
        if(a!=b)//相等就是在同一个集合里面了。在加进去就变成环了。所以是不等于
        {
            father[a]=b;
            sum=sum+road[i].w;
        }
    }
}

这样写就是跑完所有边。我们可以记数,跑n-1条边,生成树n个点需要n-1个点

 

转载于:https://www.cnblogs.com/2014slx/p/11132608.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值