【模板】最小生成树Prim 4heap

基本介绍
模板题目
代码实现

基本介绍

终于来填Prim的坑了 代码实现和最短路的Dijkstra差不多 也用的堆优化
大体意思就是说 现在图中选取一个蓝点染成白色 然后遍历与这个点相连的所有边 选取最短的边然后将另一个端点染成白色 再遍历这个点 从所有白点中找最短的 一直这样下去 stl小根堆比较好 便于每次找短的

模板题目

题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz

输入输出格式
输入格式:
第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)
接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi
输出格式:
输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz

输入输出样例
输入样例:
4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
输出样例:
7

代码实现



#include<iostream>
#include<cstdio>
#include<cctype>
#include<queue>

    using namespace std;
    #define in = read()
    typedef long long ll;
    const ll size = 1000000 + 10000;

        struct point{   ll next,to,dis;}edge[size];
        priority_queue<pair<ll , ll> , vector<pair<ll , ll> > , greater<pair<ll , ll> > > q;

        ll n,m;
        ll site,ans,total,u;
        ll head[size];
        bool exist[size];

inline ll read(){
        ll num = 0 , f = 1;   char ch = getchar();

        while(!isdigit(ch)){
                if(ch == '-')   f = -1;
                ch = getchar();
        }

        while(isdigit(ch)){
                num = num*10 + ch - '0';
                ch = getchar();
        }

        return num*f;
}

inline void add(ll x,ll y,ll z){
        edge[++site].next = head[x];
        edge[site].to = y;
        edge[site].dis = z;
        head[x] = site;
}

int main(){
        n in;   m in;
        for(int i=1;i<=m;i++){
                ll x,y,z;   x in;   y in;   z in;
                add(x,y,z);   add(y,x,z);
        }

        pair<ll , ll> x;
        q.push(make_pair(0,1));
        while(!q.empty() && total != n - 1){
                x = q.top();    q.pop();    u = x.second;
                if(exist[u])    continue;
                exist[u] = true;
                ans += x.first;
                total --;
                for(int i=head[u];i;i=edge[i].next)
                        if(!exist[edge[i].to])
                                q.push(make_pair(edge[i].dis,edge[i].to));
        }

        printf("%d",ans);
}


//COYG
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您讲解一下 HNUCM 最小生成树Prim)的算法过程。 首先,Prim 算法是一种贪心算法,用于求解带权无向连通图的最小生成树。下面是具体的算法过程: 1. 选取任意一个顶点作为起点,将其加入到生成树中。 2. 找到与已经加入到生成树中的顶点相邻的所有顶点,并计算它们与生成树的距离。 3. 从这些顶点中选取距离最小的顶点,将其加入到生成树中。 4. 重复步骤2和3,直到生成树中包含了所有的顶点。 在具体实现时,可以使用一个数组来记录每个顶点是否已经加入到生成树中,以及另一个数组来记录每个顶点与生成树的距离。每次选择距离最小的顶点时,可以使用一个最小来优化。 至于 HNUCM 最小生成树 Prim 算法的具体实现,可以参考以下代码: ```python import heapq def prim(graph): n = len(graph) visited = [False] * n distance = [float('inf')] * n distance[0] = 0 heap = [(0, 0)] result = 0 while heap: (d, u) = heapq.heappop(heap) if visited[u]: continue visited[u] = True result += d for v, weight in graph[u]: if not visited[v] and weight < distance[v]: distance[v] = weight heapq.heappush(heap, (weight, v)) return result ``` 这段代码实现了 HNUCM 最小生成树 Prim 算法的过程,其中 graph 是一个邻接表表示的带权无向连通图,每个元素是一个二元组 (v, w),表示从节点 u 到节点 v 有一条边权为 w 的边。算法的返回值是最小生成树的总权值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值