算法笔记——最小生成树

本文详细介绍了两种经典的图论算法——Prim算法和Kruskal算法,用于寻找连通图中权值最小的n-1条边以构建最小生成树。Prim算法从一个节点开始逐步扩展,每次选择与当前树连接的最小边;而Kruskal算法则是按边的权值排序,依次选取未造成环的边。这两种算法在图的遍历和并查集操作上有不同的实现策略,是图论和数据结构学习中的重要内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于n个节点的连通图,找到n-1条权值最小且无回路的边使所有节点连通。

 

Prim算法

将所有节点分为2个集合,一个是已生成树的集合U,和剩余的集合V-U

 closest[i]:第i个节点到U集合的直接连边的最近的点

lowcost[i]:第i个节点到U集合的直接连接的边的最小权值

无直接连边的点lowcost[i]=无穷大,已经在集合中的点lowcost[i]=0

void prim()
{
    memset(lowCost,inf,sizeof(lowCost));
    memset(closest,inf,sizeof(closest));
    for(int i=head[1];i;i=nxt[i])
    {
        int y=to[i];
        closest[y]=1;
        lowCost[y]=min(lowCost[y],edge[i]);//有重边时要取最小的
    }
    lowCost[1]=closest[1]=0;
    for(int i=1;i<n;i++)
    {
        int minCost=inf,u=0;
        for(int j=1;j<=n;j++)
            if(lowCost[j] && lowCost[j]<minCost)
            {
                minCost=lowCost[j];
                u=j;
            }
        if(!u)
        {
            printf("orz\n");
            return;
        }
        lowCost[u]=0;
        ans+=minCost;
        for(int j=head[u];j;j=nxt[j])
        {
            int y=to[j];
            if(edge[j]<lowCost[y])
                lowCost[y]=edge[j],closest[y]=u;
        }
    }
    printf("%d\n",ans);
}

Kruskal算法

 对边按权值从小到大排序,边的两点在不同集合则选取,在同一集合则跳过。采用并查集判断集合关系。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值