图论(5)最小生成树简单应用

news2024/11/13 19:53:36

活动 - AcWing 

参考:《算法竞赛进阶指南》-lyd

目录

一、基础算法

二、

1.最短网络(prim板子)

2.局域网(kruskal板子)

3.繁忙的都市

4.1143. 联络员

5.连接格点(预处理)


 

一、基础算法

prim和kruskal算法。可参考之前发过的文章。

二、

1.最短网络(prim板子)

 把所有农场连接起来的最短长度方案。

即最小生成树。

给的数据是邻接矩阵,所以用prim算法。

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

const int N =110;

int n;
int w[N][N];
int dist[N];
bool st[N];

int prim()
{
    memset(dist,0x3f,sizeof dist);
    dist[1]=0;
    int res=0;

    for(int i=0;i<n;i++)
    {
        int t=-1;
        for(int j=1;j<=n;j++)
            if(!st[j]&&(t==-1||dist[j]<dist[t]))
                t=j;
        res+=dist[t];
        st[t]=true;
        for(int j=1;j<=n;j++)
            dist[j]=min(dist[j],w[t][j]);
    }
    return res;
}

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>w[i][j];

    cout<<prim();
    return 0;

}

作者:yankai
链接:https://www.acwing.com/activity/content/code/content/4405659/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

2.局域网(kruskal板子)

 去边不能破坏连通,所以需要维护连通块。

处理连通块可以用并查集和dfs预处理。这里用并查集方便。

因为所有边的权值总和是不变的,所以我们算出来保留的边的权值总和越小,删掉的边的权值总和越大。

因此跑kruskal,从小到大遍历边,如果不连通,就把这条边保留用作连通,如果已经连通,就带表这条边可以去掉。

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

const int N =110,M=210;

int n,m;
struct Edge{
    int a,b,w;
    bool operator <(const Edge& t)const
    {
        return w<t.w;
    }
}e[M];

int p[N];
int res;

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

int main()
{
    cin>>n>>m;

    for(int i=1;i<=n;i++) p[i]=i;

    for(int i=0;i<m;i++) 
    {
        int a,b,c;
        cin>>a>>b>>c;
        e[i]={a,b,c};
    }
    sort(e,e+m);
    for(int i=0;i<m;i++)
    {
        int a=find(e[i].a),b=find(e[i].b),w=e[i].w;
        if(a!=b) p[a]=b;//不连通则选择该条边
        else res+=w;//已连通则除去该条边
    }
    cout<<res;
    return 0;

}

作者:yankai
链接:https://www.acwing.com/activity/content/code/content/4435790/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3.繁忙的都市

 求最小生成树,并且输出最小生成树中最大的那条边。

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

const int N =310,M=8010;

int n,m;
struct Edge{
    int a,b,w;
    bool operator< (const Edge& t) const 
    {
        return w<t.w;
    }
}e[M];
int p[N];

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


int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) p[i]=i;

    for(int i=0;i<m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        e[i]={a,b,c};
    }
    sort(e,e+m);

    int res=-0x3f3f3f3f;
    for(int i=0;i<m;i++)
    {
        int a=find(e[i].a),b=find(e[i].b),w=e[i].w;
        if(a!=b) p[a]=b,res=max(res,w);
        else continue;
    }
    cout<<n-1<<" "<<res;
}

作者:yankai
链接:https://www.acwing.com/activity/content/code/content/4435971/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

4.1143. 联络员

 把必选的选了,再跑kruskal。

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

const int N =2010,M=10010;

struct Edge{
    int a,b,w;
    bool operator<(const Edge& t) const
    {
        return w<t.w;
    }
}e[M];
int n,m;
int p[N];

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

int main()
{
    int res=0,k=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++) p[i]=i;
    for(int i=0;i<m;i++)
    {
        int type,a,b,c;
        cin>>type>>a>>b>>c;
        if(type==1)
        {
            p[find(a)]=find(b);
            res+=c;
        }
        else e[k++]={a,b,c};
    }

    sort(e,e+k);
    for(int i=0;i<k;i++)
    {
        int a=find(e[i].a),b=find(e[i].b),w=e[i].w;
        if(a!=b)
        {
            p[a]=b;
            res+=w;
        }
        else continue;
    }
    cout<<res;

}


作者:yankai
链接:https://www.acwing.com/activity/content/code/content/4436051/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

5.连接格点(预处理)

 暴力kruskal。先加纵向边,再加横向边来避免排序。

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

const int N =1010,M=N*N,K=2*M;

int n,m,k;
int ids[N][N];
struct Edge{
    int a,b,w;
    bool operator<(const Edge&t)const
    {
        return w<t.w;
    }
}e[K];

int p[M];

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

void get_edges()
{
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}, dw[4] = {1, 2, 1, 2};
    
    for(int z=0;z<2;z++)
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                for(int u=0;u<4;u++)
                {
                    if(u%2==z)//先加纵向边 因此可以不用排序
                    {
                        int x=i+dx[u],y=j+dy[u],w=dw[u];
                        if (x&&x<=n&&y&&y<=m)
                        {
                            int a=ids[i][j],b=ids[x][y];
                            if(a<b) e[k++]={a,b,w};
                        }
                    }
                }
}

int main()
{
    cin>>n>>m;
    
    for(int i =1,t=1;i<=n;i++)
        for(int j=1;j<=m;j++,t++)
            ids[i][j]=t;//坐标映射
    
    for(int i=1;i<=n*m;i++) p[i]=i;
    
    int x1,y1,x2,y2;
    while(cin>>x1>>y1>>x2>>y2)
    {
        int a=ids[x1][y1],b=ids[x2][y2];
        p[find(a)]=find(b);
    }
    
    get_edges();
    
    int res=0;
    for(int i=0;i<k;i++)
    {
        int a=find(e[i].a),b=find(e[i].b),w=e[i].w;
        if(a!=b)
        {
            p[a]=b;
            res+=w;
        }
    }
    cout<<res;
    return 0;
    
}

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

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

相关文章

影响电商发展的重要因素及电商未来的发展可能

易观分析&#xff1a;自从互联网传入中国以后&#xff0c;特别是2000年以后&#xff0c;一直保持着非常快的演变速度&#xff0c;而以互联网为基础的电商则更是发展成了中国互联网的代表性行业。中国电商的发展不仅在初期有着非常高的增速&#xff0c;有着多样化的演进路线&…

Numpy(3)—切片和索引、高级索引、Broadcast、迭代数组、广播迭代

1.切片和索引 eg1&#xff1a;我们首先通过 arange() 函数创建 ndarray对象。 然后&#xff0c;分别设置起始&#xff0c;终止和步长的参数为 2&#xff0c;7 和 2。 import numpy as npa np.arange(10) s slice(2, 7, 2) # 从索引 2 开始到索引 7 停止&#xff0c;间隔为…

【笔记】行人属性识别

【论文】https://arxiv.org/pdf/1901.07474.pdf &#xff08;以下序号与论文序列不对应&#xff09; 属性可以看作是高层语义信息&#xff0c;对视点变化和观察条件多样性具有更强的鲁棒性 本文试图解决以下几个重要问题: (1)传统和基于深度学习的行人属性识别算法之间的联系…

Java_Git:4. 分支管理

目录 1 创建合并分支 2 使用TortoiseGit实现分支管理 2.1 创建分支 2.2 合并分支 3 解决冲突 1 创建合并分支 Git会把每次的提交&#xff0c;串成一条时间线&#xff0c;即一个分支。 初始状态&#xff0c;Git只有一条时间线&#xff08;分支&#xff09;&#xff0c;这个分…

高级Spring之BeanFactory 后处理器

老样子&#xff0c;直接上代码演示&#xff0c;准备一个干净的容器&#xff1a; // ⬇️GenericApplicationContext 是一个【干净】的容器GenericApplicationContext context new GenericApplicationContext();//注册configBeancontext.registerBean("config", Conf…

【C语言学习笔记】39. 错误处理、递归

前言 C 语言不提供对错误处理的直接支持&#xff0c;但是作为一种系统编程语言&#xff0c;它以返回值的形式允许您访问底层数据。 错误处理 C 语言不提供对错误处理的直接支持&#xff0c;但是作为一种系统编程语言&#xff0c;它以返回值的形式允许您访问底层数据。在发生…

振弦采集模块配置工具VMTool的MODBUS 工具模块

振弦采集模块配置工具VMTool的MODBUS 工具模块 &#xff08; 1&#xff09; 寄存器查看 此功能模块提供标准的 MODBUS 协议寄存器显示及单个寄存器修改功能&#xff0c;通过点击扩展功能区的【 MODBUS】 标签切换到此模块&#xff0c;如下图所示。 此模块将 VMXXX 所有寄存器以…

Codeforces Round #847 (Div. 3) A~E

比赛链接&#xff1a;Dashboard - Codeforces Round #847 (Div. 3) - Codeforces 目录 A. Polycarp and the Day of Pi B. Taisia and Dice C. Premutation D. Matryoshkas E. Vlad and a Pair of Numbers A. Polycarp and the Day of Pi 题意&#xff1a;求出一个数字…

一步创建 AI 图像网站,即刻生成 AI 图像解决方案 #Graydient

过去一年当中&#xff0c;AI 画图工具非常火爆&#xff0c;一条简单的指令&#xff0c;就能快速得出超高品质的图形&#xff0c;这对于游戏开发者来说无疑是令人振奋的消息&#xff0c;尤其是没有预算和人手打造美术资源的中小团队。从网络上看到的结果来看&#xff0c;AI 的绘…

JDBC(powernode 文档)(内含源代码)

源代码下载地址链接&#xff1a;https://download.csdn.net/download/weixin_46411355/87400304 目录 JDBC概述 1.1 前言 1.2 什么是JDBC 1.3 JDBC的原理 1.4 程序员&#xff0c;JDBC&#xff0c;JDBC驱动的关系及说明 1.4.1 JDBC API 1.4.2 JDBC 驱动 1.4.3 Java程序员…

并发编程-多线程并发设计原理

并发编程-多线程&并发设计原理并发编程简介多线程&并发设计原理1 多线程回顾1.1 Thread和Runnable1.1.1 Java中的线程1.1.2 Java中的线程&#xff1a;特征和状态1.1.3 Thread和Runnable接口1.1.4 Callable1.2 synchronized关键字1.2.1 锁的对象1.2.2 锁的本质1.2.3 实现…

k8s实现controller如何远程调式?

背景&#xff1a; 使用kubebuilder和code-generate生成自定义资源代码后&#xff0c;实现管理自定义资源的controller逻辑。此时&#xff0c;需要调试controller代码逻辑&#xff0c;有2种思路。方法1&#xff1a;对该代码打包成镜像文件&#xff0c;直接部署进入k8s集群中&…

Springboot+vue中小企业合同管理系统

编写企业合同管理系统&#xff0c;让其能创建合同、修改合同、删除合同、合同变更标识、合同收款提醒、合同时间管理、合同废止标识、结束合同、合同统计、合同查询等几大功能。 (1) 创建合同 管理人员将签订后的合同的各项信息存入数据库中&#xff0c;使合同进入开始执行的…

网络编程(2)

封装和分用 1)封装:就是在数据中添加一些辅助传输的信息&#xff1b; 2)分用:就是解析这些信息 3)发送数据的时候&#xff0c;上层协议要把数据交给下层协议&#xff0c;由下层协议来添加一些信息 4)接收数据的时候&#xff0c;下层协议要把数据交给上层协议&#xff0c;有上层…

分割pdf的办法?看这里就明白了!

对于大多数办公党来说&#xff0c;困难的或许不是制作一些办公文件、文档&#xff0c;重要的是如何将这些文档以合适的形式发送给需要的人。不管是客户还是同事、上级&#xff0c;他们对文档格式、内容的要求都是有不一样的标准的。这时候我们就面临一个重要的问题了&#xff0…

Linux驱动开发:块设备驱动

这里写自定义目录标题一、块设备的简介二、块设备驱动框架1、block_device 结构体2、gendisk 结构体3、block_device_operations 结构体4、块设备 I/O 请求过程5、bio 结构体三、使用请求队列方式的块设备驱动程序1、经过第“二”部分的讲解总结&#xff0c;可以得出驱动程序的…

Java基础10:常用API(上)

Java基础10&#xff1a;常用API&#xff08;上&#xff09;一、Math二、System1. currentTimeMillis2. arraycopy三、Runtime四、Object1. toString2. equals3. clone五、Objects六、BigInteger1. 构造方法&#xff08;获取BigInteger&#xff09;2. 常用方法七、BigDecimal1. …

2023年房地产地段研究报告

房地产的投资业务中&#xff0c;选择一个好的地段&#xff0c;或者说区位&#xff0c;是十分重要的。在房地产行业&#xff0c;房价中包含地价&#xff0c;而房价上升的主要原因则是地价的上升。当房屋所处的地段深受消费者青睐、该地段的房屋供不应求时&#xff0c;房屋的价格…

Minecraft 1.19.2 Fabric模组开发 08.3D动画盔甲

我们本次在Fabric 1.19.2中实现具有动画效果的3D盔甲 效果演示效果演示效果演示 1.首先&#xff0c;为了实现这些效果&#xff0c;我们需要首先使用到一个模组:geckolib(下载地址) 找到项目的build.gradle文件&#xff0c;在repositories和dependencies中添加依赖。 reposit…

python+django校园大学生兼职系统vue357

目 录 摘 要 I Abstracts II 目 录 III 第1章 绪论 1 1.1课题背景 1 1.2研究意义 1 1.3研究内容 2 第2章 技术介绍 1 第3章 需求分析 4 3.1需求分析概述 4 3.2可行性分析 4 3.2.1经济可行性 5 3.2.2技术可行性 5 3.3系统功能设计 …