首页 > 其他分享 >【学习】最小生成树-Prim

【学习】最小生成树-Prim

时间:2023-07-30 18:55:44浏览次数:46  
标签:node Prim int 最小 tot 生成 ++ dis

最小生成树(Prim)学习笔记

展开目录

目录

Before

为了做个挖水井去学了 Prim 虽然根本不是算法的锅

前置知识是 \(dijkstra\), 有一定相似度

Prim

\(Kruskal\) 是一种适用于稀疏图的算法,而对于稠密图,也有其适用的算法——Prim。

核心思想

Prim 主要处理的是点,和 \(Kruskal\) 的针对边来处理不同。

为了方便表述,使用了“起点”和“终点”来形容,实际上所有边都是无向的。

与 \(dijkstra\) 类似,从任意一个点出发,选取这个点连接的所有边中,权值最小且终点未标记过的一条,标记这条边通向的点。再以新的点为起点,重复以上操作直到所有点都被标记。

这里除了选择的点是“距离上一个被标记的点距离最小”之外,与 \(dijkstra\) 的思想几乎相同。

时间复杂度 \(O(n^2)\), 但是在密集图中性能比 \(Kruskal\) 好。

堆优化

类似 \(dijkstra\) 的堆优化,Prim 也是有堆优化的。

在稀疏图中的时间复杂度是 \(O(m\log n)\), 但是在密集图中会被卡回 \(O(n^2)\), 甚至还不如不优化。

例题

挖水井

题面:P1550

一开始用 \(Kruskal\) 死活只有 \(10pts\), 后来换了 Prim 也只能拿 \(50pts\), 后来发现是思路错了,于是去看了个题解:

因为可以挖不止一口井,所以可以把挖井的花费看作是从水源往回运水的花费。新增点 \(n + 1\) 作为水源,把从点 \(i\) 挖井的花费看作 \(i\) 和 \(n + 1\) 之间边的边权,然后跑一个最短路的板子,大功告成。

代码是我用之前写的 dij 板子改的,足以看出 Prim 跟 dij 真的没什么大区别。

展开代码
#include <bits/stdc++.h>
#define ll long long
#define MyWife Cristallo
using namespace std;
const int N = 1e5 + 5;
int n, m, s, ans;
int head[N], to[2 * N], weal[2 * N], dis[N], nxt[2 * N], tot;
bool vis[N];
void add(int u, int v, int w) {
    to[++tot] = v;
    weal[tot] = w;
    nxt[tot] = head[u];
    head[u] = tot;
}
struct node {
    int dis, pos;
};
bool operator < (const node &x, const node &y) {
    return x.dis > y.dis;
}
priority_queue<node> q;
inline void prim() {
    int cnt = 0;
    dis[s] = 0;
    q.push((node){0, s});
    while(!q.empty()) {
        node tem = q.top();
        q.pop();
        int x = tem.pos, d = tem.dis;
        if(vis[x]) continue;
        vis[x] = 1, ++cnt;
        ans += d;
        for(int i = head[x]; i; i = nxt[i]) {
            int y = to[i], w = weal[i];
            if(dis[y] > w) {
                dis[y] = w;
                if(!vis[y]) q.push((node){dis[y], y});
            }
        }
    }
    if(cnt < n) ans = 0x7fffffff;
}
int main() {
    scanf("%d", &n);
    ++n;
    int w;
    for(int i = 1; i < n; ++i) {
        scanf("%d", &w);
        add(n, i, w);
        add(i, n, w);
    }
    for(int i = 1; i < n; ++i) for(int j = 1; j < n; ++j) {scanf("%d", &w); add(i, j, w);}
    for(int i = 1; i <= n; ++i) dis[i] = 0x7fffffff;
    s = 1;
    prim();
    printf("%d", ans);
    return 0;
}

标签:node,Prim,int,最小,tot,生成,++,dis
From: https://www.cnblogs.com/Kiichi/p/prim.html

相关文章

  • 2023.30 AI生成视频
    AI生成视频是一项复杂的任务,目前主要可以通过以下两类技术实现:1、基于GAN的视频生成GAN(生成对抗网络)可以用于生成静态图片,可以扩展到生成视频。主要思路是训练一个生成器网络,可以输出每一帧图像,然后组合成视频流。这需要大量视频数据进行训练。2、基于自动编码器的视频生成......
  • vivado生成Bitstream报错[Vivado 12-1345] Error(s) found during DRC. Bitgen not ru
    写了一个很简单的程序,2-4译码器。moduledecoder2to4(inputin1,in0,outputreg[3:0]out);always@(*)beginif({in1,in0}==2'b00)out=4'b1111;elseif({in1,in0}==2'b01)out=4......
  • Mac部署AIGC图片生成服务——基于stable-diffusion
    Mac部署AIGC图片生成服务——基于stable-diffusionAIGC即人工智能内容生成,是目前非常火的一个概念。随着各种大模型的问世,通过AI来生成内容的能已经越来越强大。本文将从应用实践方面进行介绍如何在自己的PC电脑上部署一个强大的AI图片生成服务。关于AI绘图,我相信你一定不太陌生,......
  • 靠着AI自动生成视频撸自媒体收益,赚了包辣条~
    友友们,小卷今天给大家分享下如何通过AI自动生成视频,只需要3分钟就能做出一个视频,把视频发到B站、抖音、西瓜上,还能赚包辣条哦~文末给大家准备了AI变现的案例及AIGC知识库,记得领取哦!1.收益先看看收益来源,视频平台上都有流量收益,就是你先在平台上达到赚视频收益的门槛后。后面再发的......
  • ClevopyAI - 人工智能驱动的营销文案生成工具
    ClevopyAI是一款基于人工智能技术的营销文案开发工具,可以极大地提高文案创作效率,助你轻松吸引目标受众。ClevopyAI的主要功能提供90多种营销文案模板,覆盖电商、代写、教育等多个行业图片生成器可根据文案关键词自动生成匹配的高质量图片支持一键批量生成标题、简介、文章等......
  • AI自动生成视频保姆级教程,还能赚包辣条哦~
    友友们,小卷今天给大家分享下如何通过AI自动生成视频,只需要3分钟就能做出一个视频,把视频发到B站、抖音、西瓜上,还能赚包辣条哦~文末给大家准备了AI变现的案例及AIGC知识库,记得领取哦!1.收益先看看收益来源,视频平台上都有流量收益,就是你先在平台上达到赚视频收益的门槛后。后......
  • 【Json】字符串自动生成C#类
    前言最近做项目需要和其他项目组同事做对接,需要先把相关接口的出入参定义好,再去做具体的实现。这里,既然出入参都定义好了,何不根据json直接生成好相关的类、契约层、应用等代码呢。参考1、使用VS,编辑->选择性粘贴->将JSON粘贴为类2、使用Microsoft.JScript.dll类库,https://www.......
  • HotSpot编译执行硬编码生成
    目录背景源码指令解析硬编码总结背景在一个技术群里,有一个哥们对着hotspot的源码问了个问题:源码看一下对应的源码://来源:hotspot/src/cpu/x86/vm/assembler_x86.cppvoidAssembler::notl(Registerdst){intencode=prefix_and_encode(dst->encoding());emit_int8(......
  • C++实现工资管理中的随机教师信息生成功能
    使用C++实现工资管理中的随机教师信息生成功能,想要做一个教师工资管理系统,就必须得准备好数据,但是这些数据如果用手一行一行地敲,那么工作量是非常大的,因此,我就产生了用C语言实现直接生成大量的教师基本信息的想法,需要的朋友可以参考下。教师的基本信息typedefstructteacher{......
  • C#生成PDF格式的合同文件
    生成PDF格式的合同文件,效果图如下: 一、准备工作首先C#代码操作pdf文件,需要引用一个pdf官方提供的两个dll,去网上下载,并将其添加引用到项目即可。官方下载地址 ,提取码:0jue在代码中引用usingiTextSharp.text;usingiTextSharp.text.pdf;usingSystem.IO;二、创建PDF......