最小生成树——prim算法

news/2024/11/15 6:48:16/

prim算法详解

  • prim算法简介
  • prim算法步骤
  • prim复杂度
  • prim样例题目
  • 公路修建
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例
      • 样例输入
      • 样例输出
    • 提示
  • prim样例代码

prim算法简介

P r i m Prim Prim算法是一种用于解决最小生成树问题的贪心算法。最小生成树是一个连通图的生成树,它的所有边的权重之和最小。

prim算法步骤

以下是 P r i m Prim Prim算法的详细步骤:

P r i m Prim Prim算法执行时,可以使用以下数据结构来辅助实现:

一个优先队列(最小堆):用于存储与当前最小生成树集合相连的边,并按照权重进行排序。
一个布尔数组 v i s i t e d visited visited:用于标记顶点是否已经被访问过。
以下是 P r i m Prim Prim算法的详细步骤:

初始化一个空的最小生成树集合 M S T MST MST和一个空的顶点集合 v i s i t e d visited visited
选择一个任意顶点作为起始点,并将其加入 v i s i t e d visited visited集合。
对于起始点的所有相邻边,将它们加入优先队列。
重复以下步骤,直到 v i s i t e d visited visited集合包含所有顶点:

  1. 从优先队列中取出权重最小的边 e e e,并将其另一个顶点 v v v加入 v i s i t e d visited visited集合。

  2. 如果 v v v已经被访问过,则跳过该边。

  3. 将边 e e e加入 M S T MST MST集合。

  4. 对于顶点 v v v的所有相邻边,如果另一个顶点不在 v i s i t e d visited visited集合中,则将这些边加入优先队列。返回 M S T MST MST集合作为最小生成树。

P r i m Prim Prim算法的执行过程中,优先队列的作用是选择与当前最小生成树集合相连的权重最小的边。这样可以保证每次选择的边都是当前最小生成树集合与其他顶点之间的最短边。

prim复杂度

P r i m Prim Prim算法的时间复杂度取决于优先队列的实现方式。如果使用二叉堆实现优先队列,时间复杂度为 O ( E O( E O(E l o g V ) logV) logV)

prim样例题目

公路修建

题目描述

某国有 n n n 个城市,它们互相之间没有公路相通,因此交通十分不便。为解决这一“行路难”的问题,政府决定修建公路。修建公路的任务由各城市共同完成。

修建工程分若干轮完成。在每一轮中,每个城市选择一个与它最近的城市,申请修建通往该城市的公路。政府负责审批这些申请以决定是否同意修建。

政府审批的规则如下:

  1. 如果两个或以上城市申请修建同一条公路,则让它们共同修建;
  2. 如果三个或以上的城市申请修建的公路成环。如下图,A 申请修建公路 AB,B 申请修建公路 BC,C 申请修建公路 CA。则政府将否决其中最短的一条公路的修建申请;
  3. 其他情况的申请一律同意。

一轮修建结束后,可能会有若干城市可以通过公路直接或间接相连。这些可以互相连通的城市即组成“城市联盟”。在下一轮修建中,每个“城市联盟”将被看作一个城市,发挥一个城市的作用。

当所有城市被组合成一个“城市联盟”时,修建工程也就完成了。

你的任务是根据城市的分布和前面讲到的规则,计算出将要修建的公路总长度。

输入格式

第一行一个整数 n n n,表示城市的数量。( n ≤ 5000 n \leq 5000 n5000

以下 n n n 行,每行两个整数 x x x y y y,表示一个城市的坐标。( − 1 0 6 ≤ x , y ≤ 1 0 6 -10^6 \leq x,y \leq 10^6 106x,y106

输出格式

一个实数,四舍五入保留两位小数,表示公路总长。(保证有惟一解)

样例

样例输入

4
0 0
1 2
-1 2
0 4

样例输出

6.47

提示

修建的公路如图所示:

prim样例代码

上题的正解:

#include <bits/stdc++.h>
using namespace std;
const int N=10000;
struct city { double x,y; } node[N];
double ans,minn,dis[N];
int n,m,k,now;
bool ff[N];
double far(double x1,double y1,double x2,double y2) {return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
int main() {cin >>n;for (int i=1; i<=n; i++) {cin >>node[i].x >>node[i].y;dis[i]=0x7fffffff;}dis[1]=0; ff[1]=1;for (int i=1; i<=n; i++) {minn=0x7fffffff;now=1;for (int j=2; j<=n; j++) {if (!ff[j] && dis[j]<minn) {now=j;minn=dis[j];}}ff[now]=1;ans+=dis[now];for (int j=1; j<=n; j++) {dis[j]=min(dis[j],far(node[now].x,node[now].y,node[j].x,node[j].y));}}printf("%.2lf",ans);return 0;
}

http://www.ppmy.cn/news/1024090.html

相关文章

tabBar的使用

参考Api&#xff1a;全局配置 | 微信开放文档 (qq.com) 1.使用说明 2.使用详情 3.使用案例 在全局配置的app.json中 "tabBar": {"color": "#333","selectedColor": "#d43c33","backgroundColor": "#fff&qu…

linux系统的压缩、解压详细用法,附代码举例(感觉别人写的都不够好)

文章目录 zipzip支持的选项有&#xff1a;-A 详细解释-d &#xff08;对压缩包操作&#xff09;-e &#xff08;对压缩文件加密&#xff09;-f&#xff08;只更新文件&#xff09;-g&#xff08;不显示压缩过程&#xff09;-r &#xff08;文件夹必选&#xff09;-u&#xff08…

【JAVA】包、权限修饰符、final关键字、常量、枚举、抽象类、接口

1 包 包是用来分门别类的管理各种不同类的&#xff0c;类似于文件夹、建包利于程序的管理和维护。建包语句必须在第一行建包的语法格式&#xff1a;package 公司域名倒写.项目名称。包名建议全部小写相同包下的类可以直接访问&#xff0c;不同包下的类必须导包&#xff0c;才可…

mysql一些统计实用函数

文章目录 一对多&#xff0c;多的一端只查询最新数据YEAR 年份函数MONTH 月份函数QUARTER 季度函数往前递推十年往后递推十年查询去年12月份统计身份证户籍所在地人数 一对多&#xff0c;多的一端只查询最新数据 ROW_NUMBER() over(PARTITION BY evt_id ORDER BY evt_node_rec…

昂贵的聘礼

题目链接 思路&#xff1a;每个替代物品就可以降低成本&#xff0c;可以在代替物品和被代替物品之间连一条边&#xff0c;边权为折后价&#xff0c;然后判断从每个物品出发到达物品1的最小总成本是多少&#xff0c;所以可以创建一个超级源点&#xff0c;然后在超级源点与每个物…

突破笔试:力扣计算布尔二叉树的值(medium)

1.题目链接&#xff1a;2331. 计算布尔二叉树的值 2. 题目描述&#xff1a; 给你一棵 完整二叉树 的根&#xff0c;这棵树有以下特征&#xff1a;叶子节点 要么值为 0 要么值为 1 &#xff0c;其中 0 表示 False &#xff0c;1 表示 True 。 非叶子节点 要么值为 2 要么值为 …

怎么把视频人物加马赛克?教你视频加马赛克方法

视频中加入马赛克有很多好处。首先&#xff0c;它可以用于保护个人隐私&#xff0c;特别是在涉及敏感信息或身份的情况下。马赛克可以隐藏面部、车牌号码、地址等信息&#xff0c;从而避免这些信息的泄露。其次&#xff0c;马赛克还可以用于隐藏不适当或不合适的内容&#xff0…

EVE-NG MPLS LDP LSP

目录 1 拓扑 2 配置步骤 2.1 配置接口IP 2.2 配置OSPF 2.3 使能LDP 2.3 在VPC上验证 1 拓扑 2 配置步骤 2.1 配置接口IP LER1 interface LoopBack 0ip address 1.1.1.9 32 quitinterface GigabitEthernet1/0ip address 10.1.1.1 255.255.255.0quitinterface GigabitEth…