并查集--解析关押罪犯问题(二)

2023-05-16

在网上看到一道ACM竞赛题,很巧妙的运用了并查集解决了一个现实生活的问题,然而网上的解析太少,在这里贴出来我的思考:

题目:

S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极不和谐。很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突。我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多。如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c 的冲突事件。

每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S 城Z 市长那里。公务繁忙的Z 市长只会去看列表中的第一个事件的影响力,如果影响很坏,他就会考虑撤换警察局长。

在详细考察了 N 名罪犯间的矛盾关系后,警察局长觉得压力巨大。他准备将罪犯们在两座监狱内重新分配,以求产生的冲突事件影响力都较小,从而保住自己的乌纱帽。假设只要处于同一监狱内的某两个罪犯间有仇恨,那么他们一定会在每年的某个时候发生摩擦。那么,应如何分配罪犯,才能使 Z 市长看到的那个冲突事件的影响力最小?这个最小值是多少?

输入描述:
第一行为两个正整数N和M,分别表示罪犯的数目以及存在仇恨的罪犯对数。
接下来的M行每行为三个正整数aj,bj,cj,表示aj号和bj号罪犯之间存在仇恨,其怨气值为cj。
数据保证1≤aj<bj≤N,0<cj≤1,000,000,000,且每对罪犯组合只出现一次。
输出描述:
共1行,为Z市长看到的那个冲突事件的影响力。如果本年内监狱中未发生任何冲突事件,请输出0。
输入
4 6

1 4 2534

2 3 3512

1 2 28351

1 3 6618

2 4 1805

3 4 12884

输出
3512

解析题目:

这道题不多读几遍题目,还真不好理解。

它大致讲的是,只有2个监狱,有好多罪犯,两两间有怨气,两个监狱中会有两个罪犯间有一个最大怨气,问怎样分配罪犯能让这个最大怨气值最小。

正常思考:
我们先来分析:不用算法,正常人怎么想,一般是先把怨气值排序,我简单点列一下,假如说:

12代表对象1号和2号,10代表怨气值,排序后为:

12(10) 13(9) 14(8) 23(7) 24(6) 34(5)

排好序之后呢往两个监狱放罪犯,首先一定把12分开,所以A监狱1,B监狱2,然后13也要分开,A监狱1,B监狱变成23,然后14也要分开,所以A监狱1,B监狱变成234,注意到达临界点了,再往后最大值是23,但是23已经在一个监狱里了,不能把他们分开,否则23又要和1见面,导致怨气值增大,所以至此分配结束,最大怨气值是23的怨气值7。

算法思考:
然后想办法怎样利用并查集实现这样一种分配。并查集在上一篇文章中有总结:

牛奶:并查集详谈

并查集最主要的作用是查看两个数或者点或者集合是否有联系,以及如何将没有联系的两个集合合并到一起。但是这道题是分开到两个监狱,没有联系怎么办?

这里就需要寻找联系。通过前面的正常思考,你会发现,因为1和234怨气值都比较大,所以最后234尽管有怨气,但还是走到了一起,共同对付1。所以联系的地方就在于,敌人的敌人就是我们的朋友!2是1的敌人,3是1的敌人,所以最终23走到一起。当然前提是从最大怨气排序后进行考虑。

算法的解决办法就是开一个两倍大小的并查集,通过多出来的空间作为每一名罪犯的假想敌,间接的找到自己的盟友。

具体思想可以参考这个帖子:

并查集解决关押罪犯

通过多开出一个空间,就能让有联系的人划分到一个集合。

具体C++代码详解如下:

#include<bits/stdc++.h>//万能头文件
using namespace std;
const int N = 20005;//N,M是随意开辟的空间大小,用来存放罪犯数量和矛盾对数
const int M = 100005;
/*按照边权值排序,怒气大的边放在不同的监狱,然后使用并查集维护,当发现在同一集合的时候就终止条件
*/
//原因:
//1.参数里面那个const是为了不对原来的对象修改,另外这里用引用避免了对实参的拷贝,提高效率
//2.函数加上const后缀表示此函数不修改类成员变量,如果在函数里修改了则编译报错
//即表明输入参数是只读的,也表明函数本身也是只读的。用标准来讲,该函数是query。
struct node
{
    //u,v分别代表两个罪犯,w代表他们的怨气值
    int u,v,w;
    bool operator< (const node &a) const
    {
        return w > a.w;//代表重载从大到小排序,默认值是从小到大排序的
    }
} a[M]; ///按照怒气值排序 
int fa[N * 2];
int Find(int x)
{
    return x == fa[x] ? x : fa[x] = Find(fa[x]);
}

void Union(int x,int y)
{
    int fx = Find(x);
    int fy = Find(y);
    fa[fx] = fy;
}

int main()
{
    int n,m;//罪犯数和怨气有多少对
    while(cin >> n >> m)
    {
        for(int i = 0; i < m; i ++)
        {
            //输入每对罪犯的编号及怨气值
            cin >> a[i].u  >> a[i].v >>a[i].w;
        }
        for(int i = 1; i <= n; i ++)
        {
            //初始化两个空间,让下标都等于元素值
            fa[i] = i;///表示和i同监狱的人
            fa[i + n] = i + n;///表示和i不同监狱的人
        }
        sort(a,a + m);///按照怒气值排序

        int f1,f2,f3,f4,i;
        for( i = 0 ; i < m; i ++)
        {
            f1 = Find(a[i].u);
            f2 = Find(a[i].u + n);//另一个监狱f1的对手
            f3 = Find(a[i].v);
            f4 = Find(a[i].v + n);//另一个监狱f3的对手

            //从大到小往监狱放,当放到这里发现有矛盾的两个已经在前面实现了分放
            //跳出循环,结束操作,注意大概率不是最后一组怨气
            if(f1 == f3 || f2 == f4) break;
            ///代表不能在同一个监狱
            fa[f4] = f1;
            fa[f2] = f3;
        }
        //此时打印出最大怨气值,便是所要求的最小怨气值
        if(i <= m)
        {
            cout << a[i].w << endl;

        }
        else
        {
            cout << 0 << endl;
        }
    }
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

并查集--解析关押罪犯问题(二) 的相关文章

  • C++中main函数如何调用类内函数

    C 43 43 中main函数调用类内函数的方法 以力扣209题为例 include lt iostream gt include lt vector gt using namespace std class minimum size su
  • 堆排序——手工模拟+程序实现

    堆排序的算法思想 xff1a 将待排序列构造成一个大顶堆 xff0c 此时 xff0c 整个序列的最大值就是堆顶元素 输出堆顶元素 xff0c 将堆顶元素与堆底最后一个元素进行交换 xff0c 然后 xff0c 将剩余n 1个元素重新构造成
  • 设计模式详解:原型模式

    本篇来看一下创建型模式中的第四种模式 xff1a 原型模式 仍然是先看两张图 xff0c 复习模式类型 xff0c 加深记忆 定义 xff1a 原型模式 xff1a 使用原型实例指定待创建对象的类型 xff0c 并且 通过复制这个原型来创建
  • maven镜像源及代理配置

    在公司使用网络一般需要设置代理 xff0c 我在idea中创建springboot工程时 xff0c 发现依赖下载不了 xff0c 原以为只要浏览器设置代理 xff0c 其他的网络访问都会走代理 xff0c 经过查资料设置了以下几个地方后工
  • IDEA SpotBugs代码安全审计插件

    IDEA SpotBugs代码安全审计插件 在寻找idea代码审计插件的时候 xff0c 发现Findbugs已经停止更新 xff0c 无法在idea2020 01版本运行 xff0c 由此找到SpotBugs SpotBugs介绍 Spo
  • 洛谷P1233 木棍加工

    题目描述 一堆木头棍子共有n根 xff0c 每根棍子的长度和宽度都是已知的 棍子可以被一台机器一个接一个地加工 机器处理一根棍子之前需要准备时间 准备时间是这样定义的 xff1a 第一根棍子的准备时间为1分钟 xff1b 如果刚处理完长度为
  • 如何用python写一个计算日期间隔的程序?

    如何用python写一个计算日期间隔的程序 xff1f 文章目录 如何用python写一个计算日期间隔的程序 xff1f 前言问题梳理问题解决写在后面 前言 为什么想起来写一个这样的程序呢 xff1f 前几天聊天的时候 xff0c 突然想计
  • Ubuntu 中软件包缓存文件损坏问题

    终端输入 xff1a sudo apt get update 出现如下问题 解决方法 xff1a 输入 sudo rm rf var lib apt lists
  • linux开机自启系统服务的大致原理

    Linux启动系统服务 init启动 init读取 etc inittab文件 xff0c 获取运行等级 span class token comment The default runlevel 启动时的运行等级 span id 5 in
  • apache2 配置https

    配置Apache2 https 开启ssl模块 span class token function sudo span a2enmod ssl 启用ssl站点 span class token function sudo span a2en
  • JAVA对数字+字符串,中文一二三四等特殊格式字符串进行特殊排序

    提示 xff1a 对数字 43 字符串 中文一二三四 格式字符串去重 排序 重组 可以对customSort 类的46 53行进行修改 查看新排序效果 代码如下 xff08 示例 xff09 1 SortTest 类 xff1a span
  • Linux安装Jenkins

    手把手教你在Linux上安装jenkins xff0c 废话不多说 xff0c 直接上教程 1 xff0c 用windows到官网下载jenkins 2 346 1 1 noarch rpm xff0c 下载链接 xff1a https w
  • 舵机控制(STM32F103C8T6)

    前言 本文是以STM32F103C8T6作为主控芯片 xff0c 通过PB6端口输出PWM xff0c 实现控制180 舵机 一 舵机控制原理 xff08 一 xff09 概述 舵机是一种位置伺服驱动器器 xff0c 是一种带有输出轴的小装
  • 设计模式详解:建造者模式

    今天来看一下创建新模式中的第五种模式 xff1a 建造者模式 仍然是先看两张图 xff0c 复习模式类型 xff0c 加深记忆 定义 xff1a 建造者模式 xff1a 将一个复杂对象的构建与它的表示分离 xff0c 使得同样的构建过程可以
  • 动态数码管显示(STM32F103C8T)

    一 前言 本实验是通过使用STM32F103C8T6作为主控 xff0c 八段数码 xff08 共阴极 xff09 是通过74HC245双向缓冲器控制数段选 xff0c 74HC138译码器控制位选 每个数码管显示与位号相对应的数字 xff
  • 取字模软件的使用

    1 点击运行 取字模软件 EXE 2 输入文本 xff0c 完成后按Ctrl 43 Enter按键结束输入 xff0c 如下图 3 设置字体显示的大小16 16 xff0c 如下图 xff1a 4 设置字体格式 xff0c 字体大小 xff
  • 51单片机应用篇-- --数码管60秒计时,独立按键可调

    开篇先说一句废话 本旺名字叫萨摩耶 xff0c xff0c Please 叫我旺财 xff0c xff0c xff0c 哈哈 xff0c 招财进宝嘛 xff01 缘由 本来按照我的学习计划 xff0c 我现在应该是单片机的学习过程 xff0
  • SOLIDWORKS生成URDF文件后部分文件散乱分布

    问题 xff1a SOLIDWORKS生成URDF文件在正确配置关节坐标系的情况下 xff0c 依然出现了部分零件散乱分布的情况 xff0c 例如图所示 xff1a 问题原因 xff1a 同样的零件多次装配 解决办法 xff1a 要插入同一
  • Matlab笔记:Matlab function生成C代码并运行

    1 Matlab函数 xff0c 输入 x y z roll pitch yaw xff0c 输出out为8 6的数组 2 点击Matlab coder 3 选择要生成的函数 4 定义输入类型 xff0c 输入的六个数选择double数值
  • matlab接收ROS发布的话题通信数据并实时画图

    版本说明 matlab R2021b ROS noetic matlab与ROS通信连接 在matlab和ROS连接之前 xff0c 需要先运行ROS核心 xff0c 记录ROS端的IP地址 再查找并记录matlab端 xff08 我这里是

随机推荐

  • simulink联合STM32CubeMX开发串口通信程序

    摘要 使用SIMULINK联合STM32CubeMX生成STM32F407串口发送数据代码 xff0c 发送的数据为正弦函数波形 再用SIMULINK写一个串口接收数据模型 xff0c 接收来自STM32发送的数据 xff0c 最后绘制出波
  • element 默认主题样式

    使用方法 span class token keyword import span ElementUI span class token keyword from span span class token string 39 elemen
  • 深入RUST标准库内核(一)标准库内容概述

    本书github链接 inside rust std library 本书前面章节 xff1a 深入RUST标准库内核 xff08 序言 深入RUST标准库内核 引言概述本书目的目标读者本书约定 RUST标准库体系概述core库编译器内置i
  • 深入RUST标准库内核(序言)

    对RUST的兴趣来自于Linus认真考虑将RUST作为Linux内核开发语言的新闻报道 因此开始了对RUST探索 xff0c 不久后基本上就从心底里认同了这门语言 xff0c RUST不仅是高性能及安全的语言 xff0c 它的语法设计也会带
  • 手记:把代码上传到Gitee等远程仓库的过程记录及常见问题

    很久没用git了 xff0c 指令都有点生疏了 xff0c 今天上传了一些代码到码云上 xff0c 先把过程记录下来供使用git的朋友参考 没有用图形化界面 xff0c 因为只有熟悉指令才能真正的理解领会 步骤一 xff1a 1 安装git
  • I2C总线协议原理

    首先I2C总线一共分为2根 xff0c 一根是SCL xff08 serial clock xff09 xff0c 还有一根是SDA xff08 serial data xff09 xff0c 一根是用来同步时钟的 xff0c 一根是发送接
  • 常用默认端口+URL解析+HTTP详解

    常用默认端口 http端口80 https端口443 tomcat端口8080 URL详解 http www aspxfans com 8080 news index asp boardID 61 5 amp ID 61 24618 amp
  • Vue3.0 setup函数

    setup 1 Vue3 0中一个新的配置项 xff0c 值为一个函数 2 setup是所有Composition API 组合API 表演舞台 3 组件中所用到的 xff1a 数据 方法等等 xff0c 均要配置在setup中 4 set
  • 【青训营】Go的高质量编程

    Go的高质量编程 本文内容总结自字节跳动青年训练营 第五届 后端组 什么是高质量 xff1f 各种边界条件是否完备异常情况能正常处理 xff0c 稳定性有保障易读易维护 Go语言开发者Dave Cheney指出 xff0c 编程需要遵循以下
  • c++取一个整数a从右端开始的4~7位。(注意考虑多种情况)

    c 43 43 取一个整数a从右端开始的4 xff5e 7位 xff08 注意考虑多种情况 xff09 1 思路分析及原理 4 7位的范围是10 3 10 7 1 xff0c 我们可以利用这个来判断数字的长度 从右端截取一个整数的4 7位
  • 您备案的网站未指向阿里云国内节点(不含香港)服务器,备案号可能被取消接入

    解决方法 xff1a 将你的域名添加一个二级域名 xff0c 解析到某些阿里云国内节点服务器上就行了 例如我博客域名为 www hyzhad com xff0c 就可以添加一个或者两个 A 记录 xff0c 记录值为阿里云国内节点服务器的
  • centos相关软件下载地址

    CentOS7 6 下载地址 CentOS 7 x86 64 DVD 1810 iso CentOS 7 6 DVD 版 4G http mirrors 163 com centos 7 6 1810 isos x86 64 CentOS
  • C++笔记(《C++新经典》)

    C 43 43 新经典 第1章 C C 43 43 1 1 C和C 43 43 语言的起源 特点 关系与讲解范畴1 2 C C 43 43 语言市场需求与就业需求分析1 3 再谈C C 43 43 就业1 4 搭建开发语言环境 第2章 数据
  • FileZilla连接ubuntu

    我新搭建了一个ubuntu 1 查看ssh的状态 xff1a sudo service sshd status 如果出现 xff1a ssh span class token punctuation span service span cl
  • office2016 excel复制粘贴就卡死

    原因 可能和这个帐户的缓存有关系 xff0c 或第三方软件有关系 xff0c 1 xff1a 重新安装office无效 2 xff1a 按照微软 xff0c 点文件 选项 com加载项 把里面复选框都去掉 xff0c 均无效 网上好多类似文
  • 路虽远,行则将至;事虽难,做则必成。

    新年第一天 xff0c 以奋斗为起点
  • Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build Tools“的解决办法

    在Windows系统上使用pip安装一些软件时 xff0c 会出现下面这样的问题 error Microsoft Visual C 43 43 14 0 or greater is required Get it with Microsof
  • tp5 A non-numeric value encountered解决方法

    报错信息如下 解决方法 xff1a 在对应的控制器方法加入下面这行代码即可 ini set 34 error reporting 34 34 E ALL amp E NOTICE 34
  • 自学Python day05-for循环

    语法 for 临时变量 in 序列名 xff1a xxxx 序列的意思是 xff0c 一个数据是由多个数据组成的 xff0c 例如列表 xff1a 1 2 xff0c 3 xff0c 3 xff0c 4 5 xff0c 6 7 xff0c
  • 并查集--解析关押罪犯问题(二)

    在网上看到一道ACM竞赛题 xff0c 很巧妙的运用了并查集解决了一个现实生活的问题 xff0c 然而网上的解析太少 xff0c 在这里贴出来我的思考 xff1a 题目 xff1a S 城现有两座监狱 xff0c 一共关押着N 名罪犯 xf