Luogu P1525 [NOIp2010提高组]关押罪犯 | 并查集
这一道题,我用了并查集来做。
在此题中,并查集的作用就是:将同一个监狱里的罪犯合并到一起。
思路:将每对罪犯之间的怨气值从大到小排序,再依次把他们分到不同的两个监狱里,当发现这一对罪犯已经在同一个监狱里时,就说明他们已经不能再分开了(分开了就不是最优了,仔细想想为什么)。此时,这一对罪犯之间的怨气值就是答案。值得注意的是,当没有冲突发生时,要记得输出0。那么,我们应该如何用并查集实现以上的思路呢?首先说几个关键词语的含义:
1、“敌人”:如果一对罪犯被分到两个不同的监狱里,那么他们就互为“敌人”。
2、“朋友”:如果一对罪犯被分到一个监狱里,那么他们就互为“朋友”。
需要明确的一点是“敌人”的“敌人”,就是“朋友”。
当分开一对罪犯时(假设他们的名字叫x和y),若x还没有“敌人”,那么就记录y为x的“敌人”(因为他们被分开了嘛);否则就把y所在的集合与x的“敌人”所在的集合合并,这是因为x是y的“敌人”,所以x的“敌人”就是y的“敌人”的“敌人”(即“朋友”),可以发现x的“敌人”和y一定是关在同一监狱里的,然后再对y的“敌人”也这样处理一遍就行了。这样我们就达到了把同一个监狱里的罪犯合并到一起的目的,处理时若发现此时处理的这一对罪犯已经在同一集合中了,则输出他们之间的怨气值作为答案。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct edge//存罪犯之间的怨气关系
{
int u;
int v;
int w;
}e[100005];
bool cmp(edge x,edge y)//将怨气值从大到小排序的排序函数
{
return x.w>y.w;
}
//f为用作实现并查集的数组,表示的是第i个罪犯的“祖先”是谁,enemy储存的是第i个罪犯的某个敌人
int f[20005],enemy[20005];
int find_(int x)//并查集查找函数
{
if(f[x]==x) return x;
return f[x]=find_(f[x]);
}
void merge_(int x,int y)//并查集合并函数
{
int t1=find_(x),t2=find_(y);
if(t1!=t2) f[t2]=t1;
return;
}
int main()
{
int n=0,m=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) f[i]=i;//并查集初始化
for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].u,&e[i].v,&e[i].w);
sort(e+1,e+m+1,cmp);//将怨气值从大到小排序
for(int i=1;i<=m;i++)
{
if(find_(e[i].u)==find_(e[i].v))//如果这一对罪犯已经在同一个监狱里
{
printf("%d",e[i].w);//直接输出他们之间的怨气值
return 0;//结束程序
}
//如果这一对罪犯仍能分开
if(!enemy[e[i].u]) enemy[e[i].u]=e[i].v;//如果u还没有敌人,那么v就是他的敌人
else merge_(e[i].v,enemy[e[i].u]);//否则,就将v与u的敌人合并
if(!enemy[e[i].v]) enemy[e[i].v]=e[i].u;//如果v还没有敌人,那么u就是他的敌人
else merge_(e[i].u,enemy[e[i].v]);//否则,就将u与v的敌人合并
}
printf("%d",0);//记得输出0
return 0;
}
Luogu P1525 [NOIp2010提高组]关押罪犯 | 并查集的更多相关文章
- NOIP2010提高组 关押罪犯 -SilverN
(洛谷P1525) 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”( ...
- 洛谷 P1525 关押罪犯 NOIp2010提高组 (贪心+并查集)
题目链接:https://www.luogu.org/problemnew/show/P1525 题目分析 通过分析,我们可以知道,这道题的抽象意义就是把一个带边权的无向图,分成两个点集,使得两个集合 ...
- [NOIp2010提高组]关押罪犯
OJ题号:洛谷1525 思路:贪心. 先将所有的人按怨气值从大到小排一下,然后依次尝试将双方分入两个不同的监狱,如果失败(即已分入相同的监狱),则输出这个怨气值. #include<cstdio ...
- NOIP2010提高组] CODEVS 1069 关押罪犯(并查集)
这道这么简单的题目还写了这么久.. 将每个会发生冲突的两人的怒气进行排序,然后从怒气大到小,将两个人放到不同监狱中.假如两人都已经被放置且在同一监狱,这就是答案. ------------------ ...
- NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...
- 洛谷P1525关押罪犯——并查集
题目:https://www.luogu.org/problemnew/show/P1525 并查集+贪心,从大到小排序,将二人分在不同房间,找到第一个不满足的即为答案. 代码如下: #include ...
- NOIP 2010 关押罪犯 并查集 二分+二分图染色
题目描述: S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值" ...
- P1525 关押罪犯 并查集
题目描述 SS城现有两座监狱,一共关押着NN名罪犯,编号分别为1-N1−N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值) ...
- [noip2010]关押罪犯 并查集
第一次看的时候想到了并查集,但是不知道怎么实现: 标解,f[i]表示i所属的集合,用f[i+n]表示i所属集合的补集,实现的很巧妙,可以当成一个使用并查集的巧妙应用: #include<iost ...
随机推荐
- Mac下Sublime Text3配置Python开发环境
设置Sublime Text的语法为python View -> syntax ->python 设置编译环境(默认python版本2.7) Tools -> Build Syste ...
- scrum项目冲刺_day02总结
摘要:今日完成任务. 1.appUI页面完成 2.图像识别正在进行 总任务: 一.appUI页面(已完成) 二.首页功能: 1.图像识别功能 2.语音识别功能 3.垃圾搜索功能 4.相关新闻爬取 三. ...
- java线程day-02
1.什么是线程 * 线程是程序执行的一条路径, 一个进程中可以包含多条线程 * 多线程并发执行可以提高程序的效率, 可以同时完成多项工作 2.多线程的应用场景 * 红蜘蛛同时共享屏幕给多个电脑 * 迅 ...
- uni-app开发基本知识点
uni-app: 开始:必须要有一个根view结点. 外部文件引用方式的变化: js要require进来,变成了对象. <script> var util = require('../.. ...
- jmeter之图形结果
jmeter监听器中的图形报表如何分析,反正第一次看到图时,不觉明厉害. 样本数目:是总共发送到服务器的请求数. 最新样本:是代表时间的数字,是服务器响应最后一个请求的时间. 吞吐量:是服务器每分钟处 ...
- Modern PHP interface 接口
The right way /dev/hell Code Response.php 接口 demo: modern-php/├── data│ └── stream.txt└── interfac ...
- python读Excel方法(xlrd)
在我们做平常工作或自动化测试中都会遇到操作excel,Python处理exc相当顺手,如何通过python操作excel,当然python操作excel的库有很多,比如pandas,xlwt/xlrd ...
- 让前端的下拉框支持单选、多选及全选,后台MyBaits解决方案
目录 一.解决思路 二.请求参数 三.后台相关代码 四.Mybatis注意要点 一.解决思路 让前端的下拉框支持单选.多选及全选,后台让Mybatis使用** trim **标签拼接动态SQL,实 ...
- windows使用VS编译python源码
使用VS2021编译python源码 说明,使用VS2019也是可以的. 环境准备 对于VS2019首要要安装必要的环境 到python官网下载源码压缩包以及解压(红色箭头任选一个都行) 打开下载好的 ...
- SQL SERVER数据库权限分配
1,新建 只能访问某一个表的只读用户. --添加只允许访问指定表的用户: exec sp_addlogin '用户名','密码','默认数据库名' ...