ccf 数据中心 prim+邻接链表+堆100分

这篇博客主要记录了使用C++实现Prim算法解决数据中心最小生成树问题的过程。通过邻接链表和堆结构优化,即使在边稀疏图中也能达到100分的效果。作者强调了在实现过程中需要注意的一个常见误区,即在处理堆中元素时,不能仅依赖于之前是否访问过的判断,因为堆的出堆顺序并不保证。
摘要由CSDN通过智能技术生成

这道题网上大多是用kruskal做的,因为准备ccf的关系,准备学习c++,于是希望实现prim练练手,写博客来积累一下学到的数据结构。

这道题题意就是求最小生成树中权值最大的边。因为它给的数据量问题,是个边稀疏图,用kruskal做效率更高,但是优化的prim也可以做到满分。
prim+邻接链表+堆实现。

堆中存放的是边,用pair表示,first表示边权值,second表示到达点的序号。count表示已访问过的顶点个数,n表示顶点总个数

核心逻辑是:
1.入堆一个虚拟边,权值为0,到达点为起始点。
2.弹出堆顶元素,若second访问过了,则continue,若没有访问过,则count++,res = first
3.if count == n then return res
4.将所有到达点未访问过的邻接边入堆 ,goto 2

误区(就是我开始写错了):在4中判断过到达点未访问过,所以不用在2中判断second是否已经访问过,这是不对的。原因是循环的判断顺序是按照权值的,而不是入堆的顺序,所以可能在之前判断未访问过的到达点边,在出堆的时候已经访问过了。

#include<bits/stdc++.h>
using namespace std;
/*
prim算法
*/
typedef pair<int,int> wl;
//默认第一关键字排序,这里的空格是必要的,否则会成移位符 greater表示升序队列,即小顶堆 
priority_queue <wl,vector<wl>,greater<wl> >q;
struct Edge{
   
	int nextNode;
	int cost;
};
const int N = 100001;
vector<Edge> edge[N];
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值