第三章 图论 No.4最小生成树的简单应用

news2024/11/16 8:33:07

文章目录

      • 裸题:1140. 最短网络
      • 裸题:1141. 局域网
      • 裸题:1142. 繁忙的都市
      • 裸题:1143. 联络员
      • 有些麻烦的裸题:1144. 连接格点

存在边权为负的情况下,无法求最小生成树

image.png

裸题:1140. 最短网络

1140. 最短网络 - AcWing题库
image.png
套个prim的板子即可

#include <iostream>
#include <cstring>
using namespace std;

const int N = 110, INF = 0x3f3f3f3f;
int g[N][N];
int dis[N]; bool st[N];
int n;

int prim()
{
    memset(dis, 0x3f, sizeof(dis));
    int res = 0;
    for (int i = 0; i < n; ++ i )
    {
        int x = -1;
        for (int j = 1; j <= n; ++ j ) 
            if (!st[j] && (x == -1 || dis[x] > dis[j])) x = j;
        st[x] = true;
        if (i && dis[x] == INF) return INF;
        if (i) res += dis[x];
        
        for (int y = 1; y <= n; ++ y )
            dis[y] = min(dis[y], g[x][y]);
    }
    return res;
}

int main()
{
    scanf("%d", &n);
    for (int i = 1; i <= n; ++ i )
        for (int j = 1; j <= n; ++ j )
            scanf("%d", &g[i][j]);
            
    printf("%d\n", prim());
    return 0;
}

裸题:1141. 局域网

1141. 局域网 - AcWing题库
image.png

裸题,稀疏图,套个kruskal的板子就行
需要注意的是:题目给定的图可能存在多个连通块,若使用prim算法,需要对每个连通块求最小生成树,但是使用kruskal能直接求出所有连通块的最小生成树

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

const int N = 110, M = 210;
struct Edge
{
    int x, y, w;
    bool operator<(const Edge& e) const 
    {
        return w < e.w;
    }
}edges[M];

int p[N];
int n, m;

int find(int x)
{
    if (x != p[x]) p[x] = find(p[x]);
    return p[x];
}

int kruskal()
{
    sort(edges, edges + m);
    for (int i = 1; i <= n; ++ i ) p[i] = i;
    int cnt = 0, res = 0;
    for (int i = 0; i < m; ++ i )
    {
        auto t = edges[i];
        int x = edges[i].x, y = edges[i].y, w = edges[i].w;
        x = find(x), y = find(y);
        if (x != y)
        {
            cnt ++ ;
            res += w;
            p[x] = y;
        }
    }
    return res;
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; ++ i )
        scanf("%d%d%d", &edges[i].x, &edges[i].y, &edges[i].w);
        
    int sum = 0;
    for (int i = 0; i < m; ++ i ) sum += edges[i].w;
    printf("%d\n", sum - kruskal());
    return 0;
}

裸题:1142. 繁忙的都市

1142. 繁忙的都市 - AcWing题库
依然是套kruskal的板子
image.png

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 310 ,M = 8010;
struct Edge
{
    int x, y, w;
    bool operator<(const Edge& e) const
    {
        return w < e.w;
    }
}edges[M];

int n, m;
int p[N];

int find(int x)
{
    if (x != p[x]) p[x] = find(p[x]);
    return p[x];
}

int kruskal()
{
    sort(edges, edges + m);
    int res = 0;
    for (int i = 1; i <= n; ++ i ) p[i] = i;
    for (int i = 0; i < m; ++ i )
    {
        auto t = edges[i];
        int x = t.x, y = t.y, w = t.w;
        x = find(x), y = find(y);
        if (x != y)
        {
            res = max(res, w);
            p[x] = y;
        }
    }
    return res;
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; ++ i )
        scanf("%d%d%d", &edges[i].x, &edges[i].y, &edges[i].w);
        
    printf("%d %d\n", n - 1, kruskal());
    return 0;
}

裸题:1143. 联络员

1143. 联络员 - AcWing题库
image.png

添加所有必选的边,维护并查集,然后再对非必选的边做kruskal


#include <iostream>
#include <algorithm>
using namespace std;

const int N = 2010, M = 10010;
struct Edge
{
    int x, y, w;
    bool operator<(const Edge& e) const 
    {
        return w < e.w;
    }
}edges[M];

int n, m, cnt;
int p[N];

int find(int x)
{
    if (x != p[x]) p[x] = find(p[x]);
    return p[x];
}

int kruskal()
{
    int res = 0;
    for (int i = 0; i < cnt; ++ i )
    {
        auto t = edges[i];
        int x = t.x, y = t.y, w = t.w;
        x = find(x), y = find(y);
        if (x != y)
        {
            res += w;
            p[x] = y;
        }
    }
    return res;
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++ i ) p[i] = i;
    
    int t, x, y, d;
    int res = 0;
    while ( m -- )
    {
        scanf("%d%d%d%d", &t, &x, &y, &d);
        if (t == 1)
        {
            x = find(x), y = find(y);
            if (x != y) p[x] = y;
            res += d;
        }
        else
        {
            edges[cnt].x = x, edges[cnt].y = y, edges[cnt].w = d;
            cnt ++ ;
        }
    }
    sort(edges, edges + cnt);
    res += kruskal();
    printf("%d\n", res);
    
    return 0;
}

有些麻烦的裸题:1144. 连接格点

1144. 连接格点 - AcWing题库
image.png

点阵为图中的点,将二维坐标转换成一维,作为点的编号
添加已有连线后,做kruskal即可

#include <iostream>
#include <algorithm>
using namespace std;

const int N = 1010;
struct Edge
{
    int x, y, w;
    bool operator<(const Edge& e) const 
    {
        return w < e.w;
    }
}edges[2 * N * N];

int n, m, cnt = 1;
int p[N * N];
int g[N][N]; // 二维到一维
int dx[3] = { 0, 1, 0 }, dy[3] = { 0, 0, 1 };

int find(int x)
{
    if (x != p[x]) p[x] = find(p[x]);
    return p[x];
}

int kruskal()
{
    int res = 0;
    for (int i = 0; i < cnt; ++ i )
    {
        auto t = edges[i];
        int x = t.x, y = t.y, w = t.w;
        x = find(x), y = find(y);
        if (x != y)
        {
            res += w;
            p[x] = y;
        }
    }
    return res;
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; ++ i )
        for (int j = 1; j <= m; ++ j )
            g[i][j] = cnt ++ ;
    
    for (int i = 1; i < cnt; ++ i ) p[i] = i;
    int x1, x2, y1, y2;
    while (~scanf("%d%d%d%d", &x1, &y1, &x2, &y2))
    {
        int x = g[x1][y1], y = g[x2][y2];
        x = find(x), y = find(y);
        if (x != y) p[x] = y;
    }
    
    cnt = 0;
    for (int i = 1; i <= n; ++ i )
        for (int j = 1; j <= m; ++ j )
            for (int k = 1; k <= 2; ++ k )
            {
                int a = i + dx[k], b = j + dy[k];
                if (a >= 1 && a <= n && b >= 1 && b <= m)
                {
                    int x = g[i][j], y = g[a][b];
                    edges[cnt ++ ] = { x, y, k };
                }
                    
            }
            
    sort(edges, edges + cnt);
    printf("%d\n", kruskal());
    
    return 0;
}

debug:n * m的矩阵中,相邻两点之间存在一条边,那么矩阵中的边数应该为m(n-1) + n(m-1),大概就是2 * n * n,数组开小了导致SF
尽量不要在for循环中定义除了循环变量之外的变量

image.png
需要注意的是,200万条边进行排序会消耗很多时间,由于边的权值只有1和2,所以可以先添加权值为1的边,再添加权值为2的边

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/838565.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【三极管双稳态电路】2022-3-5

缘由multisim仿真问题-嵌入式-CSDN问答

《算法竞赛·快冲300题》每日一题:“ 盲文文字编码”

《算法竞赛快冲300题》将于2024年出版&#xff0c;是《算法竞赛》的辅助练习册。 所有题目放在自建的OJ New Online Judge。 用C/C、Java、Python三种语言给出代码&#xff0c;以中低档题为主&#xff0c;适合入门、进阶。 文章目录 题目描述题解C代码Java代码Python代码 “ 盲…

《cuda c编程权威指南》05 - cuda矩阵求和

目录 1. 使用一个二维网格和二维块的矩阵加法 1.1 关键代码 1.2 完整代码 1.3 运行时间 2. 使用一维网格和一维块的矩阵加法 2.1 关键代码 2.2 完整代码 2.3 运行时间 3. 使用二维网格和一维块的矩阵矩阵加法 3.1 关键代码 3.2 完整代码 3.3 运行时间 1. 使用一个二…

==和equals():比较对象等不等?

引言&#xff1a; 在编程中&#xff0c;我们常常需要判断两个对象是否相等。而在Java中&#xff0c;有两种常用的方法&#xff1a;使用""运算符和调用equals()方法。这两个方法有什么区别呢&#xff1f;它们又有哪些有趣的应用呢&#xff1f;让我们一起来探索一下吧&…

RTT学习笔记12-KConfig 语法学习

KConfig 语法学习 RTT 官方教程 https://www.rt-thread.org/document/site/#/development-tools/build-config-system/Kconfig 我自己写的IIC配置 menuconfig BSP_USING_I2C # I2C 菜单bool "Enable I2C BUS" # 提示I2C 菜单default n # 默认不使能I2C 菜单…

第三章 图论 No.3 flody之多源汇最短路,传递闭包,最小环与倍增

文章目录 多源汇最短路&#xff1a;1125. 牛的旅行传递闭包&#xff1a;343. 排序最小环&#xff1a;344. 观光之旅345. 牛站 flody的四个应用&#xff1a; 多源汇最短路传递闭包找最小环恰好经过k条边的最短路 倍增 多源汇最短路&#xff1a;1125. 牛的旅行 1125. 牛的旅行 …

Camera之PhysicalCameraSettingsList/SurfaceMap/CameraMetadata/RequestList的关系(三十二)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药. 更多原创,欢迎关注:Android…

打开的idea项目maven不生效

方法一&#xff1a;CtrlshiftA&#xff08;或者help---->find action&#xff09;&#xff0c; 输入maven&#xff0c; 点击add maven projects&#xff0c;选择本项目中的pom.xml配置文件&#xff0c;等待加载........ 方法二&#xff1a;view->tools windows->mave…

使用Python将Word文档转换为PDF的方法

摘要&#xff1a; 文介绍了如何使用Python编程语言将Word文档转换为PDF格式的方法。我们将使用python-docx和pywin32库来实现这个功能&#xff0c;这些库提供了与Microsoft Word应用程序的交互能力。 正文&#xff1a; 在现实生活和工作中&#xff0c;我们可能会遇到将Word文…

软考高级架构师——2、操作系统

一、进程管理 • 进程的状态&#xff08;★&#xff09; • 进程的同步与互斥&#xff08;★★★★&#xff09; 临界资源&#xff1a;诸进程间需要互斥方式对其进行共享的资源&#xff0c;如打印机、磁带机等 临界区&#xff1a;每个进程中访问临界资源的那段代码称为临界区…

ubuntu18.04 虚拟机与主机不通,虚拟机无法上网,导致无法git clone代码

问题前置&#xff1a;修改了固定ip。 虚拟机ip&#xff1a; 虚拟机设置NAT模式&#xff1a; 主机配置网络适配器&#xff1a;分配ipv4192.168.152.2保持与虚拟机的虚拟网关192.168.152.0,192.168.152.1在同一网段。虚拟机静态ip为192.168.152.146 虚拟机&#xff0c;网关&#…

【项目 线程4】3.12生产者消费者模型 3.13条件变量 3.14信号量 C++实现生产者消费者模型

3.12生产者消费者模型 生产者消费者模型中的对象&#xff1a; 1、生产者 2、消费者 3、容器 若容器已满&#xff0c;生产者阻塞在这&#xff0c;通知消费者去消费&#xff1b;若容器已空&#xff0c;则消费者阻塞&#xff0c;通知生产者去生产。生产者可以有多个&#xff0c;消…

供水管网漏损监测,24小时保障城市供水安全

供水管网作为城市生命线重要组成部分&#xff0c;其安全运行是城市建设和人民生活的基本保障。随着我国社会经济的快速发展和城市化进程的加快&#xff0c;城市供水管网的建设规模日益增长。然而&#xff0c;由于管网老化、外力破坏和不当维护等因素导致的供水管网漏损&#xf…

RabbitMQ的安装

RabbitMQ的安装 1、Windows环境下的RabbitMQ安装步骤 使用的版本&#xff1a;otp_win64_23.2 rabbitmq-server-3.8.16 版本说明&#xff1a;https://www.rabbitmq.com/which-erlang.html#compatibility-matrix 1.1 下载并安装erlang RabbitMQ 服务端代码是使用并发式语言…

8.5作业

要求实现AB进程对话 a.A进程先发送一句话给B进程&#xff0c;B进程接收后打印 b.B进程再回复一句话给A进程&#xff0c;A进程接收后打印 c.重复1.2步骤&#xff0c;当收到quit后&#xff0c;要结束AB进程 A进程 #include<stdio.h> #include<string.h> #include&…

Linux文本三剑客---grep、sed、awk

目录标题 1、grep1.1 命令格式1.2命令功能1.3命令参数1.4grep实战演练 2、sed2.1 认识sed2.2命令格式2.3常用选项options2.4地址定界2.5 编辑命令command2.6用法演示2.6.1常用选项options演示2.6.2地址界定演示2.6.3编辑命令command演示 3、awk3.1认识awk3.2常用命令选项3.3awk…

中国中医中药元宇宙 中药材价格缘何“狂飙”

◇相比去年同期&#xff0c;有超200个常规品种涨幅高于50%&#xff0c;25个常用大宗药材涨幅超200%&#xff0c;个别品种甚至涨价4至9倍 ◇在中药材价格普遍高涨的情况下&#xff0c;部分市场仓库库存数量也较多&#xff0c;出现囤积居奇倾向 ◇“不少游资和热钱涌入中药材市场…

MyBatis查询数据库之一(概念+创建项目+基础交互)

目录 1.MyBatis是什么&#xff1f; 2.为什么学习MyBatis&#xff1f; 3. 怎么学 MyBatis 4.第⼀个MyBatis查询 4.1 添加MyBatis框架支持 4.1.1老项目添加MyBatis 4.1.2 新项目添加MyBatis 4.2 配置连接字符串和MyBatis 4.2.1 配置连接字符串 4.2.2 配置 MyBatis 中的…

小白电脑装机(自用)

几个月前买了配件想自己装电脑&#xff0c;结果最后无法成功点亮&#xff0c;出现的问题是主板上的DebugLED黄灯常亮&#xff0c;即DRAM灯亮。对于微星主板的Debug灯&#xff0c;其含义这篇博文中有说明。 根据另一篇博文&#xff0c;有两种可能。 我这边曾将内存条和主板一块…

设计模式之模板方法

一、概述 定义一个操作中的算法的骨架&#xff0c;将一些步骤延迟到子类中。 TemplateMethod使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。 二、适用性 1.一次性实现一个算法的不变的部分&#xff0c;并将可变的行为留给子类来实现。 2.各子类中公共…