牛客小白月赛74 F题解

news2024/10/6 22:25:02

文章目录

  • 最便宜的构建
    • 问题建模
    • 问题分析
      • 1.分析所求
      • 2.方法1用并查集判断k个点集是否连通,不连通则由小到大添加边
        • 代码
      • 3. 方法2使用带权并查集维护当前集合所连通的点集个数
        • 代码
      • 4.方法3通过二分确定值
        • 代码

最便宜的构建

在这里插入图片描述在这里插入图片描述

问题建模

给定n个点m条边的带权无向图,以及k个点集,求选择一些边,使得k个点集内的所有点都连通的边集中最大边权最小的值为多少。

问题分析

1.分析所求

所求的边集首先要满足使得k个点连通,其次让所选边集中的最大值尽可能小。则对于所有的边首先得按权值从小到大考虑,使用了当前边能否连通k个点集。

2.方法1用并查集判断k个点集是否连通,不连通则由小到大添加边

代码

#include<bits/stdc++.h>

#define x first
#define y second
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N =1e5+10, Mod = 998244353, P = 2048;
struct edge{
    int u,v,d;
};
edge e[N];
bool st[N];
int p[N];
int a[N];
int idx;
int n,m;
bool cmp(edge e1,edge e2){
    return e1.d<e2.d;
}
int find(int x){
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}

void solve() {
    cin >>n >>m;
    for(int i=0;i<m;i++){
        int u,v,d;
        scanf("%d %d %d",&u,&v,&d);
        e[i]={u,v,d};
    }
    int k;
    cin>>k;
    for(int i=0;i<k;i++){
        int s;
        cin >>s;
        for(int j=0;j<s;j++){
            int x;
            scanf("%d",&x);
            ///将k个点集中所需的点都存起来,方便使用
            if(!st[x])  st[x]=true,a[++idx]=x;
        }
    }   

    sort(e,e+m,cmp);
    for(int i=1;i<=n;i++)   p[i]=i;
    int pos=0;
    ///枚举k个点集内的点,若有不连通则按权值由小到大添加边
    for(int i=2;i<=idx;i++){
        while(find(a[i])!=find(a[i-1])){
            int fa=find(e[pos].u),fb=find(e[pos].v);
            if(fa!=fb)  p[fa]=fb;
            pos++;
        }
    }
    cout <<(pos?e[pos-1].d:0) <<endl;
}   


int main() {
    int t = 1;
    //cin >> t;
    while (t--) solve();
    return 0;
}

3. 方法2使用带权并查集维护当前集合所连通的点集个数

代码

#include<bits/stdc++.h>

#define x first
#define y second
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N =1e5+10, Mod = 998244353, P = 2048;
struct edge{
    int u,v,d;
};
edge e[N];
int d[N],p[N];
int cnt,n,m;

bool cmp(edge e1,edge e2){
    return e1.d<e2.d;
}
int find(int x){
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}

int check(){
    sort(e,e+m,cmp);
    for(int i=1;i<=n;i++)   p[i]=i;

    int res=0;
    if(cnt<=1)  return res;
    for(int i=0;i<m;i++){
        int fa=find(e[i].u),fb=find(e[i].v);
        if(fa==fb)  continue;
        d[fb]+=d[fa];
        p[fa]=fb;
        res=e[i].d;
        ///若当前点所在集合内包含的所需点数量等于所需点个数,则表示k个点集已连通
        if(d[fb]==cnt)  break;
    }

    return res;
}

void solve() {
    cin >>n >>m;
    for(int i=0;i<m;i++){
        int u,v,d;
        scanf("%d %d %d",&u,&v,&d);
        e[i]={u,v,d};
    }
    int k;
    cin>>k;
    for(int i=0;i<k;i++){
        int s;
        cin >>s;
        for(int j=0;j<s;j++){
            int x;
            scanf("%d",&x);
            ///将该点的权值设为1,代表以该点为祖宗结点的集合内有1个所需点
            if(!d[x])  d[x]=1,cnt++;
        }
    }   
    cout <<check() <<"\n";
}   


int main() {
    int t = 1;
    //cin >> t;
    while (t--) solve();
    return 0;
}

4.方法3通过二分确定值

由于我们是从小到大考虑使用当前边后能否连通k个点集,则可以考虑通过二分的方法,先确定一个边权,然后检查使用小于等于该边权的边能否将k个点集都连通,是否连通则采用并查集来处理。

代码

#include<bits/stdc++.h>

#define x first
#define y second
using namespace std;
typedef unsigned long long ULL;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const int N =1e5+10, Mod = 998244353, P = 2048;
struct edge{
    int u,v,d;
};
edge e[N];
bool st[N];
int p[N];
int a[N];
int idx;
int n,m;
bool cmp(edge e1,edge e2){
    return e1.d<e2.d;
}
int find(int x){
    if(x!=p[x]) p[x]=find(p[x]);
    return p[x];
}

bool check(int x){
    for(int i=1;i<=n;i++)   p[i]=i;

    for(int i=0;i<m;i++){
        if(e[i].d>x)    break;
        int pa=find(e[i].u),pb=find(e[i].v);
        if(pa!=pb)  p[pa]=pb;
    }
	
    ///判断k个点集内的点是否都连通
    for(int i=2;i<=idx;i++){
        if(find(a[1])!=find(a[i])){
            return false;
        }
    }

    return true;
}

void solve() {
    cin >>n >>m;
    for(int i=0;i<m;i++){
        int u,v,d;
        scanf("%d %d %d",&u,&v,&d);
        e[i]={u,v,d};
    }
    int k;
    cin>>k;
    for(int i=0;i<k;i++){
        int s;
        cin >>s;
        for(int j=0;j<s;j++){
            int x;
            scanf("%d",&x);
            ///将k个点集中所需的点都存起来,方便使用
            if(!st[x])  st[x]=true,a[++idx]=x;
        }
    }   

    sort(e,e+m,cmp);
    int l=0,r=1e9;
    while(l<r){
        int mid=(l+r)>>1;
        if(check(mid))  r=mid;
        else l=mid+1;
    }

    cout <<l <<"\n";
}   


int main() {
    int t = 1;
    //cin >> t;
    while (t--) solve();
    return 0;
}

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

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

相关文章

初阶结构体(超详解)

初阶结构体 1. 结构体的声明1.1 结构的基础知识1.2 结构的声明1.3 结构成员的类型1.4 结构体变量的初始化和定义 2. 结构体的访问3. 结构体传参 1. 结构体的声明 1.1 结构的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的每个成员可以是不同类型的变量 结…

电商高并发设计之SpringBoot整合Redis实现布隆过滤器

文章目录 问题背景前言布隆过滤器原理使用场景基础中间件搭建如何实现布隆过滤器引入依赖注入RedisTemplate布隆过滤器核心代码Redis操作布隆过滤器验证 总结 问题背景 研究布隆过滤器的实现方式以及使用场景 前言 本篇的代码都是参考SpringBootRedis布隆过滤器防恶意流量击穿缓…

让数据管理由繁至简的低代码开发平台

随着社会数字化能力的快速升级&#xff0c;各行各业正逐渐迈向数字化转型的新时代。尤其是AI的爆发&#xff0c;数据智能技术正在彻底改变着这个行业的面貌&#xff0c;随着越来越多的企业开始将人工智能、机器学习和大数据分析技术应用到其业务中&#xff0c;数据的价值正在得…

深度解剖动态内存管理

> 作者简介&#xff1a;დ旧言~&#xff0c;目前大一&#xff0c;现在学习Java&#xff0c;c&#xff0c;c&#xff0c;Python等 > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 望小伙伴们点赞&#x1f44d;收藏✨加关注哟&#x1f495;&#x1…

【项目 进程8】 2.17 内存映射(1) 2.18内存映射(2)

文章目录 2.17 内存映射&#xff08;1&#xff09;内存映射内存映射相关系统调用使用内存映射实现父子进程间通信使用内存映射实现没有关系的进程间的通信 2.18内存映射&#xff08;2&#xff09;内存映射的注意事项使用内存映射实现内存拷贝的功能匿名映射 2.17 内存映射&…

【Spring】学习Spring需要掌握的核心设计思想

目录 一、Spring是什么 二、什么是IoC容器 1、什么是容器 2、什么是IoC 3、Spring IoC 4、DI&#xff08;依赖注入&#xff09; 4.1、IoC和DI的区别 5、 DL&#xff08;依赖查找&#xff09; 一、Spring是什么 我们通常所说的Spring指的是Spring Framework&#xff08;…

DAY55:单调栈(一)每日温度+下一个更大元素Ⅰ

文章目录 739.每日温度栈数据结构单调栈思路单调栈原理单调栈注意点判断条件工作过程分析 完整版 496.下一个更大元素Ⅰ思路映射思路 完整版总结 739.每日温度 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 an…

2023年第四届“华数杯”数学建模思路 - 案例:异常检测

文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常检测 异常…

【Java】UWB高精度工业人员安全定位系统源码

基于VueSpring boot前后端分离架构开发的一套UWB技术高精度定位系统源码。 UWB高精度人员定位系统提供实时定位、电子围栏、轨迹回放等基础功能以及各种拓展功能,用户可根据实际需要任意选择搭配拓展功能。该系统简易部署&#xff0c;方便使用&#xff0c;实时响应。UWB高精度定…

Java on Azure Tooling 6月更新|标准消费和专用计划及本地存储账户(Azurite)支持

作者&#xff1a;Jialuo Gan - Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎阅读 Java on Azure 工具的六月更新。在本次更新中&#xff0c;我们将介绍 Azure Spring Apps 标准消费和专用计划支持以及本地存储账户&…

二叉树迭代遍历

PS:以下代码均为C实现 1.二叉树前序遍历 力扣 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 class Solution { public:vector<int> preorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> str;TreeNode* curroot;whil…

【波浪动态特效】基于jquery实现页面底部波浪动画效果(附完整源码下载)

文章目录 写在前面涉及知识点实现效果1、搭建页面1.1、创建两个片区1.2、创建波浪区域1.3、静态页面源码 2、JS实现波浪效果2.1 动画原理2.2 动画源码 3、源码分享3.1 百度网盘3.2 123云盘3.3 邮箱留言 总结 写在前面 想必搭建过企业官网的大多数对这个效果不陌生吧&#xff0…

备战秋招 | 笔试强训21

目录 一、选择题 二、编程题 三、选择题题解 四、编程题题解 一、选择题 1、设一个有序的单链表中有n个结点&#xff0c;现要求插入一个新结点后使得单链表仍然保持有序&#xff0c;则该操作的时间复杂度&#xff08;&#xff09; A. O(log2n) B. O(1) C. O(n2) D. O(n) 2…

网络中通过IP地址查找位置

display ip routing-table 查看路由表 display vlan 查看vlan 信息 display stp brief 查看生成树信息 display mac-address 查看mac 地址表 display arp 查看arp表 SW1 SW2

海量小文件传输慢的原因以及对应的优化方案

在日常工作中&#xff0c;我们经常遇到需要传输一些小文件的情况&#xff0c;但是当小文件的数量很多的时候&#xff0c;为什么小文件传输的速度就会变得很慢呢&#xff1f;为什么复制许多较小的文件时&#xff0c;小文件传输效率就会降低呢&#xff1f;针对这些问题&#xff0…

MyBatis查询数据库(3)

前言&#x1f36d; ❤️❤️❤️SSM专栏更新中&#xff0c;各位大佬觉得写得不错&#xff0c;支持一下&#xff0c;感谢了&#xff01;❤️❤️❤️ Spring Spring MVC MyBatis_冷兮雪的博客-CSDN博客 前面我们讲解了MyBatis增删改查基本操作&#xff0c;下面我们来深入了解M…

谷歌语音助手战略调整:开发 AI 新版,调整裁员计划

北京时间8月2日晚间&#xff0c;谷歌通过对 “谷歌助手” 团队进行调整和裁员&#xff0c;意图改变其开发方向。经过此次变动&#xff0c;谷歌计划借助最新的生成式人工智能技术和大型语言模型来提升 谷歌助手 的能力。此次调整表明语音助手市场未达到先前的预期。 亚马逊旗下的…

PT Industrial Security Incident Manager 扩展了对 Emerson 和 GE Fanuc 控制器的支持

&#x1f504; 我们发布了 PT Industrial Security Incident Manager (PT ISIM) 深度流程流量分析系统的下一套专业知识。 有哪些新功能&#xff1f; 1. 改进了 GE Fanuc (Emerson) GE-SRTP 协议的操作。该协议专为 GE Fanuc 控制器与工程软件&#xff08;Proficy Machine E…

ArmSoM-W3之RK3588安装Qt+opencv+采集摄像头画面

1. 简介 场景&#xff1a;在RK3588上做qt开发工作 RK3588安装Qtopencv采集摄像头画面 2. 环境介绍 这里使用了OpenCV所带的库函数捕获摄像头的视频图像。 硬件环境&#xff1a; ArmSoM-RK3588开发板、&#xff08;MIPI-DSI&#xff09;摄像头 软件版本&#xff1a; OS&…

angular框架——node_modules引入ng-zorro-antd问题

发生错误 在安装npm包&#xff08;ng-zorro-antd&#xff09;的时候&#xff0c;报错如下 原因 项目依赖的ng-zorro-antd版本号和引用包的17.0.2版本号不一致&#xff0c;项目使用的16.13.1版本号太高了&#xff0c;无法解析依赖树中低版本。 解决方案 &#xff1a; 命令修…