codevs1069关押罪犯(并查集)
S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N。他们之间的关系自然也极
不和谐。很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突。我们用“怨
气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之
间的积怨越多。如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并
造成影响力为c 的冲突事件。
每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,
然后上报到S 城Z 市长那里。公务繁忙的Z 市长只会去看列表中的第一个事件的影响力,
如果影响很坏,他就会考虑撤换警察局长。
在详细考察了N 名罪犯间的矛盾关系后,警察局长觉得压力巨大。他准备将罪犯们在
两座监狱内重新分配,以求产生的冲突事件影响力都较小,从而保住自己的乌纱帽。假设只
要处于同一监狱内的某两个罪犯间有仇恨,那么他们一定会在每年的某个时候发生摩擦。那
么,应如何分配罪犯,才能使Z 市长看到的那个冲突事件的影响力最小?这个最小值是少?
第一行为两个正整数N 和M,分别表示罪犯的数目以及存在仇恨的罪犯对数。
接下来的M 行每行为三个正整数aj,bj,cj,表示aj 号和bj 号罪犯之间存在仇恨,其怨气值为cj。数据保证,且每对罪犯组合只出现一次。
共1 行,为Z 市长看到的那个冲突事件的影响力。如果本年内监狱
中未发生任何冲突事件,请输出0。
4 6
1 4 2534
2 3 3512
1 2 28351
1 3 6618
2 4 1805
3 4 12884
3512
罪犯之间的怨气值如下面左图所示,右图所示为罪犯的分配方法,市长看到的冲突事件
影响力是3512(由2 号和3 号罪犯引发)。其他任何分法都不会比这个分法更优。
【数据范围】
对于30%的数据有N≤ 15。
对于70%的数据有N≤ 2000,M≤ 50000。
对于100%的数据有N≤ 20000,M≤ 100000。
————————————————————————————————————————我是奇妙的分割线——————————————————————————————————
看到这道题蒟蒻我的第一个想法就是贪心,因为题目要求使最大的怨气值最小,所以只要把怨气值排序,再尽量满足有怨气的罪犯不分到同一个监狱,直到一定会起冲突。但是直接枚举判断监狱里是否有这个罪犯的敌人非常麻烦,需要枚举每一个在这个监狱里的罪犯,判断是否有冲突,肯定会TLE。于是,蒟蒻想到了刚学的并查集。
科普部分:想学并查集的请浏览http://blog.csdn.net/dellaserss/article/details/7724401/(某大神的并查集详解(转))
于是使用并查集,但还需要一个神奇的技巧:
我们只需要记录每个罪犯最近一次枚举到的敌人,在第二次枚举到这个罪犯时,将他的敌人和上一次枚举到的敌人合并(即放到同一个监狱),这样一个罪犯的所有敌人都会被合并(放到同一个监狱),这样当两个互为敌人的罪犯出现在同一个监狱时,就知道会起冲突。
最后,再梳理一下解题流程:
1、对怨气值排序;
2、按怨气值从大到小枚举每对罪犯,再用并查集处理;
3、没有起冲突的罪犯时不要忘了输出0;
———————————————————————————————————————我是奇妙的分割线x2—————————————————————————————————
当AC时我特别开心(一个蒟蒻做出水题的开心),看题解发现有大神用二分图(orz orz orz orz orz orz orz orz orz orz orz 我不会)
代码如下:
var e,x,y:array[..]of longint;
f,a:array[..]of longint;
n,m,i:longint;
procedure qs(l,r:longint);
var i,j,m,t:longint;
begin
i:=l; j:=r; m:=e[(l+r)shr ];
repeat
while e[i]>m do inc(i);
while e[j]<m do dec(j);
if i<=j then begin
t:=e[i]; e[i]:=e[j]; e[j]:=t;
t:=x[i]; x[i]:=x[j]; x[j]:=t;
t:=y[i]; y[i]:=y[j]; y[j]:=t;
inc(i); dec(j);
end;
until i>j;
if l<j then qs(l,j);
if i<r then qs(i,r);
end;
function find(n:longint):longint;
begin
if f[n]=n then exit(n);
find:=find(f[n]);
f[n]:=find;
end;
procedure merge(a,b:longint);
var x,y:longint;
begin
x:=find(a); y:=find(b);
if x<>y then f[x]:=y;
end;
begin
readln(n,m);
for i:= to m do
read(x[i],y[i],e[i]);
qs(,m);
for i:= to n do
f[i]:=i;
for i:= to m do begin
if find(x[i])=find(y[i])then begin
writeln(e[i]);
halt;
end;
if a[x[i]]<> then merge(a[x[i]],y[i]);
if a[y[i]]<> then merge(x[i],a[y[i]]);
a[x[i]]:=y[i]; a[y[i]]:=x[i];
end;
writeln();
end.
codevs1069关押罪犯(并查集)的更多相关文章
- NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...
- NOIP 2010 关押罪犯 并查集 二分+二分图染色
题目描述: S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值" ...
- Luogu P1525 [NOIp2010提高组]关押罪犯 | 并查集
题目链接 这一道题,我用了并查集来做.在此题中,并查集的作用就是:将同一个监狱里的罪犯合并到一起. 思路:将每对罪犯之间的怨气值从大到小排序,再依次把他们分到不同的两个监狱里,当发现这一对罪犯已经在同 ...
- [noip2010]关押罪犯 并查集
第一次看的时候想到了并查集,但是不知道怎么实现: 标解,f[i]表示i所属的集合,用f[i+n]表示i所属集合的补集,实现的很巧妙,可以当成一个使用并查集的巧妙应用: #include<iost ...
- NOIP2010提高组] CODEVS 1069 关押罪犯(并查集)
这道这么简单的题目还写了这么久.. 将每个会发生冲突的两人的怒气进行排序,然后从怒气大到小,将两个人放到不同监狱中.假如两人都已经被放置且在同一监狱,这就是答案. ------------------ ...
- 洛谷P1525关押罪犯——并查集
题目:https://www.luogu.org/problemnew/show/P1525 并查集+贪心,从大到小排序,将二人分在不同房间,找到第一个不满足的即为答案. 代码如下: #include ...
- LUOGU 1525 关押罪犯 - 并查集拆点(对立点) / 二分+二分图染色
传送门 分析: 并查集: 第一步先将所有矛盾从大至小排序,显然先将矛盾值大的分成两部分会更优. 普通的并查集都只能快速合并两个元素至同一集合,却不能将两个元素分至不同集合. 对于将很多数分成两个集合, ...
- P1525 关押罪犯 并查集
题目描述 SS城现有两座监狱,一共关押着NN名罪犯,编号分别为1-N1−N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值) ...
- luogu1525 [NOIp2011]关押罪犯 (并查集)
先从大到小排序,看到哪个的时候安排不开了 给每个人拆成两个,如果x和y有矛盾,就给x和y‘.y和x’连边:如果a和b(或a'和b')在同一个集合里,说明他们一定要在同一个监狱里. #include&l ...
- 关押罪犯 - 并查集&优先队列
题目地址:http://www.51cpc.com/web/problem.php?id=4261 Summarize: 此题最巧妙的是“敌人的敌人就是朋友!”,故需先将敌对关系放入优先队列,按怨恨值 ...
随机推荐
- Mysql高级之事务
原文:Mysql高级之事务 通俗的说事务: 指一组操作,要么都成功执行,要么都不执行.---->原子性 在所有的操作没有执行完毕之前,其他会话不能够看到中间改变的过程-->隔离性 事务发生 ...
- 【转】在PC上测试移动端网站和模拟手机浏览器的5大方法
查了很多资料,尝试了大部分方法,下面将这一天的努力总结下分享给大家,也让大家免去看那么多文章,以下介绍的方法,都是本人亲自测试成功的方法,测试环境winxp. 一.Chrome*浏览器 chrome模 ...
- 在PHP中连接数据库时获取最后的一个ID
在SQL中获取最后的一个id 只需要加上where条件对id进行排序就可以了 但是在PHP中 有一种最新的方法 使用mysql_insert_id();就可以获得最大的id .
- [转]Android与电脑局域网共享之:Samba Server
大家都有这样的经历,通过我的电脑或网上邻居访问另一台计算机上的共享资源,虽然电脑和手机之间可以有多种数据传输方式,但通过Windows SMB方式进行共享估计使用的人并不是太多,下面我就简单介绍一下, ...
- 了解你的被测系统(why?)
了解你的被测系统(why?) 如何做好系统集成测试[二.了解你的被测系统] 如果看完了第一篇文章,你的答案是Yes.我们可以继续讨论如何做系统集成测试啦. 了解你的被测系统(why?) 一如既 ...
- linux时间校准设置,解决与本地时间不一致问题
时间安装脚本 从NTP上把时间同步到本地 cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 更新本地时间 ntpdate us.pool.nt ...
- D13
=-=由于本人有极度强迫症啊.. 然后这个博客又不能改顺序.. 前几天由于台风是在宾馆写题..简直各种没有效率..所以今天就先草草写下题解,之后再完善吧 T1:字符串处理 c++的话,解决读空格继续读 ...
- YARN
YARN 介绍 Apache Hadoop YARN作为hadoop的子项目加入到Hadoop Common (core libraries), Hadoop HDFS (storage) and H ...
- [实验]通过内核Patch去掉iOS-v4.3.3的沙盒特性
环境: 1.Mac OS X 10.9.2 2.xcode 5.1.1 3.gcc 4.8 4.redsn0w 0.9.15b3 前提: 1.获取 iOS 4.3.3 的kernelcache,并解密 ...
- JavaScript事件的几个细节
JavaScript事件的几个细节 一.是捕获还是冒泡 昨天被问到一个问题:事件流有几个阶段?在这几个阶段中,事件一共发生几次? 问题很简单,但对于事件一共发生几次有点乱.总觉得捕获也能触发事件.冒泡 ...