题目来源:洛谷

题目描述

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。

输入输出样例

输入样例#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%的数据有N≤15。

对于70%的数据有N≤2000,M≤50000。

对于100%的数据有N≤20000,M≤100000。

解析:

这道题可以作为并查集扩展域的入门题目,在做过这道题后,我们会对扩展域有更深刻的理解。


【什么是扩展域】

鄙人薄见:扩展域用以维护较抽象的对象之间的逻辑关系,由于有点抽象,所以理解起来有点费劲。

扩展域将数据之间的关系分类,将对象之间不同的关系分开讨论,并在这些数据之间建立联系。

而且,这样的关系最好要具有传递性,这样某对象之间的关系就能相互导出。

这里难以理解的一点主要是,扩展域仅仅维护对象之间的关系,而不关心对象的其他特征

PS:目前为止,我只见到过维护二元关系的扩展域并查集。

就拿这一题举例吧,假设x和y在同一个监狱里,那么他们必然不会在不同的监狱里;如果x和y在不同的监狱里,那他们就不会在同一个监狱里。

听起来有点绕,我们分析一下:如果有一组关系表明x和y在同一个监狱,那么就可以推导出另一组关系x和y不会在不同的监狱。反之亦然。

于是我们可以给一个并查集划分几个不同的种类(或者叫域),用来存放对象之间不同的关系。

说说这道题我的解题思路吧:按照怨气值把较大的两个人分开,直到分不下去(两个罪犯无法避免在同一个监狱里)。

1.边权值大到小排序。
2.每次维护并查集:
x_self表示x所在监狱,x_another表示另1个监狱。
删一条边就把x_self和y_another合并,y_self和x_another合并。
前提条件:分不下去:二者在一个监狱(x_self=y_self||x_another=y_another)。

参考代码:

 #include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#define N 100010
using namespace std;
struct p{
int x,y,val;
}a[N];
bool operator<(p a,p b){
return a.val>b.val;
}
int head[N<<],fa[N<<],tot,n,m;
int get(int x)
{
if(fa[x]==x) return x;
return fa[x]=get(fa[x]);
}
void merge(int x,int y)
{
x=get(x),y=get(y);
if(x!=y) fa[x]=y;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=*n;i++) fa[i]=i;
for(int i=;i<=m;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].val);
}
sort(a+,a+m+);
int ans=;
for(int i=;i<=m;i++){
int x_self=a[i].x,x_another=a[i].x+n;
int y_self=a[i].y,y_another=a[i].y+n;
if(get(x_self)==get(y_self)||get(x_another)==get(y_another)){
ans=a[i].val;break;
}
merge(x_self,y_another);
merge(x_another,y_self);
}
cout<<ans<<endl;
return ;
}

P1525 关押罪犯[扩展域并查集]的更多相关文章

  1. 洛谷P1525 关押罪犯(并查集、二分图判定)

    本人蒟蒻,只能靠题解AC,看到大佬们的解题思路,%%%%%% https://www.luogu.org/problemnew/show/P1525 题目描述 S城现有两座监狱,一共关押着N名罪犯,编 ...

  2. codevs1069关押罪犯(并查集)

    题目描述 Description S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极 不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨 ...

  3. 洛谷1525 关押罪犯NOIP2010 并查集

    问题描述 S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两 ...

  4. NOIP2010 关押罪犯 (并查集)

    若x,y有关系 将x与y的补集, y与x的补集建立关系 ; maxm=; ..maxm,..] of longint; f:..maxn*] of longint; i,j,m,n,x,y,z:lon ...

  5. AcWing 257. 关押罪犯 (并查集)打卡

    题目:https://www.acwing.com/problem/content/description/259/ 题意:有两个监狱,监狱里面有很多犯人,现在有很多对冲突,还有个冲突值,现在问我们怎 ...

  6. 洛谷 P1525 关押罪犯==codevs 1069 关押罪犯[NOIP 2010]

    P1525 关押罪犯 513通过 1.4K提交 题目提供者该用户不存在 标签图论并查集NOIp提高组2010 难度普及+/提高 提交该题 讨论 题解 记录 最新讨论 咳咳.竟MLE了. 囧.运行时错误 ...

  7. 洛谷 P1525 关押罪犯

    题目链接 https://www.luogu.org/problemnew/show/P1525 题目描述 S城现有两座监狱,一共关押着N名罪犯,编号分别为1−N.他们之间的关系自然也极不和谐.很多罪 ...

  8. NOI2001 食物链【扩展域并查集】*

    NOI2001 食物链 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形.A 吃 B,B吃 C,C 吃 A. 现有 N 个动物,以 1 - N 编号.每个动物都是 A,B,C 中的 ...

  9. POJ1733 Parity game 【扩展域并查集】*

    POJ1733 Parity game Description Now and then you play the following game with your friend. Your frie ...

随机推荐

  1. Docker Overview

    Docker 是一个用于开发.交付和运行应用的开放平台,Docker 设计用来更快的交付你的应用程序.Docker 可以将你的应用程序和基础设施层隔离,并且还可以将你的基础设施当作程序一样进行管理.D ...

  2. netty内存数据缓冲区使用策略

    主要是通过AbstractByteBufAllocator类实现的ByteBuffer的申请. 代码如下: @Override public ByteBuf ioBuffer(int initialC ...

  3. [转帖]插曲:大白话带你认识Kafka

    插曲:大白话带你认识Kafka 2019-11-18 21:58:27 从事Java 阅读数 2更多 分类专栏: java Kafaka   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA ...

  4. Spark学习(1) Spark入门

    什么事spark Spark是一种快速.通用.可扩展的大数据计算引擎.项目是用Scala进行编写,基于内存计算的 包括交互式查询和流处理 spark内置项目 Spark SQL:是 Spark 用来操 ...

  5. 高并发 多线程批量ping工具 nbping简介和使用

    nbping 简介 nbping是为解决局域网大批量IP实例或主机探活,采用go协程并发处理,可以自定义并发的协程数量和输出结果.效率远高于现有的批量ping工具. nbping具备如下特性 - 支持 ...

  6. CentOS7安装Prometheus(二进制)

    一.概述 Prometheus是由SoundCloud开发的开源监控报警系统和时序列数据库(TSDB).Prometheus使用Go语言开发,是Google BorgMon监控系统的开源版本. 环境说 ...

  7. POI2015 WYC

    也许更好的阅读体验 \(\mathcal{Description}\) 给定一张n个点m条边的带权有向图,每条边的边权只可能是1,2,3中的一种.将所有可能的路径按路径长度排序,请输出第k小的路径的长 ...

  8. vuex的Store简单使用过程

    介绍 Store的代码结构一般由State.Getters.Mutation.Actions这四种组成,也可以理解Store是一个容器,Store里面的状态与单纯的全局变量是不一样的,无法直接改变st ...

  9. server.port 在单元测试中,调用的类或者方法这个地方获取到的端口号就会变成-1

    @Value("${server.port}") 本文链接:https://blog.csdn.net/weixin_38342534/article/details/886985 ...

  10. websocket-shap 函数Broadcast的使用方法

    Broadcast:在websocket-shap函数的定义是:向WebSocket服务中的每个客户端发送数据,类似于广播的效果 如果要使用异步发送,可使用BroadcastAsync函数. 在源码中 ...