并查集——关押罪犯(洛谷 P1525)
题目选自洛谷P1525
此题是一道很经典,而且很好的题目。思路也十分的新颖,比较的难以捉摸。
题面大意:(人性翻译)
给你m对矛盾关系,每对关系分别涉及到x,y两人,矛盾值为w
请你判断分配x和y到两个集合中,能否避免冲突
如能避免请输出0,如果冲突不可避免,请输出最小的矛盾值
以上是本人自己的“翻译”理解,接下来请看算法分析
算法分析
大致解析
先逆序sort一遍
假设a虚拟的敌人为a',b虚拟敌人是b',以此类推
a和b是敌人,连线a和b',b和a',代表是朋友
当出现两个敌人在一个“朋友圈”中的时候,矛盾,输出并终止程序(原来排过序了,保证此时冲突最大)
没有矛盾,输出0
详细解析
本题,因为说了有“边权值”(我理解为矛盾值),所以要求出现矛盾情况下的最小边权值显然是需要排序的
那么问题又来了,我们要按照什么方法进行分配呢?
我们不妨这样想:两个人a,b有仇,那么把他们放在一起显然会打起来,那么我们还不如把a与b的其他敌人放在一起,
因为这样可能会出现“敌人的敌人就是朋友”的情况,恰好a与b的其他敌人之间没有矛盾,那么他们就可以放在同一个集合中,反之b对a亦然。
那么我们不妨这样实现: 首先需要并查集初始化
(1)先把所有的矛盾关系按照矛盾值从大到小排一遍序,
(2)接下来每次操作取出一个关系,看矛盾的两个人x和y是否已经分配到同一个集合中(并查集找父亲即可),那么还分如下两种情况:
如果在一起那么显然会打起来(会出现矛盾),那么直接输出当前的边权(矛盾值)即可(此时保证是最小矛盾值,因为已经排序了)
如果不在同一组,则按照“敌人的敌人就是朋友”的原则,把x与y的其他敌人分在同一组,y与x的其他敌人分在同一组
不断进行以上操作最终可以得到答案
题目描述
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≤10^9,且每对罪犯组合只出现一次。
输出格式
共 1 行,为 Z 市长看到的那个冲突事件的影响力。如果本年内监狱中未发生任何冲突事件,请输出 0
。
输入输出样例
输入 1
4 6 1 4 2534 2 3 3512 1 2 28351 1 3 6618 2 4 1805 3 4 12884
输出 1
3512
说明/提示
【输入输出样例说明】罪犯之间的怨气值如下面左图所示,右图所示为罪犯的分配方法,市长看到的冲突事件影响力是 3512(由 2 号和 3 号罪犯引发)。其他任何分法都不会比这个分法更优。
【数据范围】
对于 30\%30%的数据有 N≤15。
对于 70\%70% 的数据有 N≤2000,M≤50000。
对于 100\%100% 的数据有 N≤20000,M≤100000。
解题代码:
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{int x,y,z;
}f[100001];
bool cmp(node a,node b){ //排序return a.z > b.z;
}
int n,m,a[20001],b[20001]; //a[i]表示i的父亲,b[i]表示i的敌人
void init(){ //初始化for(int i=1;i<=n;i++) a[i]=i;
}
int find(int x){ //查找if(a[x]==x) return x;return a[x] = find(a[x]);
}
void merge(int x,int y){ //合并a[find(x)] = find(y);
}
bool check(int x,int y){ //判断if(find(x)==find(y)) return true;return false;
}
int main(){cin>>n>>m;init();for(int i=1;i<=m;i++)scanf("%d%d%d",&f[i].x,&f[i].y,&f[i].z);sort(f+1,f+1+m,cmp);for(int i=1;i<=m+1;i++){//如果不可避免的分在同一监狱if(check(f[i].x,f[i].y)){printf("%d",f[i].z);break;}else{//否则就可以分开if(!b[f[i].x]) b[f[i].x] = f[i].y;else {merge(b[f[i].x],f[i].y);}//将敌人的敌人合并if(!b[f[i].y]) b[f[i].y] = f[i].x;else {merge(b[f[i].y],f[i].x);}}}return 0;
}
并查集——关押罪犯(洛谷 P1525)相关推荐
- 关押罪犯洛谷P1525
题目+评测传送门 思路 其实这一题有2种不同的思路,但是由于我实在是太蒟蒻了,只会其中一种,另一种看了半天都不知道它在讲什么/(ㄒoㄒ)/~~ 首先,我们要学习一下二分图及其判断方法博客,然后这个题目 ...
- 并查集——程序自动分析(洛谷 P1955)
题目选自洛谷P1955 比较复杂一点的并查集题目,还用到了离散化的思想 首先明确一点:相等具有传递性,不相等不具有传递性(Eg:若x1等于x2,x2等于x3时,显然x1=x3.但当x1不等于x2,x2 ...
- 并查集——村村通(洛谷 P1536)
题目选自洛谷P1536 并查集的变相考察类型的题目 先处理每一条存在的边,即把每条存在的边所连接的两个结点用并查集合并起来. 然后通过记录不同的代表元个数,就可以知道有多少个集合,即有多少个连通块了. ...
- NOIP2010关押罪犯题解(洛谷P1525) (并查集)
NOIP2010关押罪犯题解(洛谷P1525) (并查集) 日常膜拜dalao:财神万岁!!!!!!!!!!!!!!!!!!!!! 日常凌晨三点水题解..(原谅我中间断更了几天,,马上分班考试了竞赛顾 ...
- 洛谷P1525 关押罪犯
P1525 关押罪犯 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用" ...
- 关押罪犯-并查集、贪心
题目来源:Acwing 257.关押罪犯&洛谷 P1525 [NOIP2010 提高组] 关押罪犯 思路来源:这里 题目描述 S 城现有两座监狱,一共关押着 N 名罪犯,编号分别为1~N. 他 ...
- [NOIP2010提高组]关押罪犯
题目:洛谷P1525.Vijos P1776.codevs1069. 题目大意:有一些罪犯,两个罪犯之间可能会发生冲突,冲突有个影响力,而如果两个罪犯在不同监狱里,就可以避免冲突.现在有两个监狱,要你 ...
- #洛谷oj:P1525 [NOIP2010 提高组] 关押罪犯
洛谷oj:P1525 [NOIP2010 提高组] 关押罪犯 #题目描述 #一看很明显是贪心算法 加排序 因为 这个中间最大值的那一对肯定是不会在一起的 从大到小来看 所有点对都尽量不要在一个监狱 # ...
- P1525 关押罪犯(扩展域并查集/二分图)
洛谷题目链接 输入 4 6 1 4 2534 2 3 3512 1 2 28351 1 3 6618 2 4 1805 3 4 12884 输出 3512 1.并查集 有意思的一道并查集的题,需要一些 ...
最新文章
- 【组队学习】一月微信图文索引
- 基于DSP的数字振荡器C语言编程,基于DSP的数字振荡器的设计与实现.pdf
- 【Java学习笔记七】常用数据对象之数组
- 企业会计准则2020版pdf_2020年下半年CATTI三级笔译中译英真题+参考答案+原文件汉英对照PDF版...
- 一个php请求的执行过程,PHP程序执行的过程原理
- sqoop导出数据时:ERROR tool.ExportTool: Error during export: Export job failed!解决
- geopandas下载问题
- 面试题(二十五)设计模式
- Git入门|Git的基本用法(一)
- Nature Cell Biology:揭示 PI3K-Akt 信号通路新机制,有望成为癌症治疗新靶点
- pytorch LSTM的股价预测
- although 与 though 的区别
- 0x800703e3复制文件错误
- Ubuntu20.04解决安装synergy失败问题
- Java的反射机制 及 操作Class类
- 终于弄清楚SDH、MSTP 、OTN和PTN的关系了
- 你必须知道的495个C语言问题电子书pdf下载
- 如何测量距离?ABViewer热门技术问答精选合集!
- 实验记录 | 6/3 修改somatic.pl中的文件路径
- 魔改hustoj源码使其支持显示队名和队员及女队标志
热门文章
- IT历史:IT史重大失败教训
- OD反汇编EXE添加一个启动时的消息框
- systemctl命令
- 戴尔电脑正在准备自动修复_戴尔如何建立社区为开放的未来做准备
- 谈判如何在谈判中_如何避免通过工资谈判把钱留在桌上
- 只想在老家找份工作很难吗_当您只想完成工作时,为什么公开工作会很困难
- ajax请求成功和失败方法_创新需要反馈和失败的新方法
- 亚马逊 ai 解雇_解雇社区成员
- 美国 otc 数字货币_美国数字公共图书馆的免费藏书量是第一年的三倍
- includes(), startsWith(), endsWith()