Description

  S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N。他们之间的关系自然也极不和谐。很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突。我们用“怨 气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多。如果两名怨气值为 c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c的冲突事件。
每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S城Z市长那里。公务繁忙的Z市长只会去看列表中的第一个事件的影响力, 如果影响很坏,他就会考虑撤换警察局长。
  在详细考察了N名罪犯间的矛盾关系后,警察局长觉得压力巨大。他准备将罪犯们在两座监狱内重新分配,以求产生的冲突事件影响力都较小,从而保住自己的乌纱帽。假设只要处于同一监狱内的某两个罪犯间有仇恨,那么他们一定会在每年的某个时候发生摩擦。那么,应如何分配罪犯,才能使Z市长看到的那个冲突事件的影响力最小?这个最小值是多少?

Input

  输入文件名为 prison.in。输入文件的每行中两个数之间用一个空格隔开。
  第一行为两个正整数N和M,分别表示罪犯的数目以及存在仇恨的罪犯对数。
  接下来的M行每行为三个正整数 aj,bj,cj,表示aj号和bj号罪犯之间存在仇恨,其怨气值为cj。数据保证1≤aj

Output

  输出文件prison.out共1行,为Z市长看到的那个冲突事件的影响力。如果本年内监狱 中未发生任何冲突事件,请输出0。

Sample Input

4 6
1 4 2534
2 3 3512
1 2 28351
1 3 6618
2 4 1805
3 4 12884

Sample Output

3512

Hint

【样例说明】  

  罪犯之间的怨气值如下面左图所示,右图所示为罪犯的分配方法,市长看到的冲突事件 影响力是3512(由2号和3号罪犯引发)。其他任何分法都不会比这个分法更优。
  
【数据范围】
  对于30%的数据有N≤15。
  对于70%的数据有N≤2000,M≤50000。 
  对于100%的数据有N≤20000,M≤100000。

Thinking

  这道题首先要想到并查集思路,这是解题的基础。首先考虑问题,如何安排罪犯才能做到最优决策?明显的可以看出,要尽量先安排仇恨值大的组合,将他们放到不同的监狱里。从大到小进行决策直到发现有某一组组合已经在同一个监狱里,那么输出他们的仇恨值就是最终的答案。现在问题又来了,第一组罪犯可以轻松地随意安排到两个监狱中,但是从第二组开始,两个人到底应该各自去哪一个监狱呢?

  这时要改变思路,既然维护罪犯在哪一个监狱不方便,那么我们干脆维护某两个罪犯不在一个监狱好了。考虑到并查集的本职工作是维护某两点在一个集合,不能很好地处理不在一个集合的情况,所以我们要曲线救国,通过保存某个点的“敌人”集合来代表和他不在一个监狱的罪犯,间接地实现维护某两点不在一个集合的情况。在加入关系的时候进行判断,如果某两点已经在一个集合,说明他们无论如何也安排不到不同的两个监狱了,输出仇恨值即可。

  至此算法框架基本浮现。

  (P.s 用并查集保存两点不在一个集合还可以使用对立点的方式,即给每一个实点都建立一个与之对立的虚点。当读取到A与B不在同一集合的信息时,将A与B',B与A'分别连边,这样也可以表示A与B不在同一集合。判断过程与上面的方法相同,实现起来也很简单,大家不妨试一下)

Code

 #include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; struct edge
{
int x,y,v;
}cr[];
bool cmp(edge a,edge b) {return a.v>b.v;}
int n,m;
int an[],pr[],en[]; int get_father(int x)
{
if(pr[x]==x) return x;
pr[x]=get_father(pr[x]);
return pr[x];
}
void Union(int x,int y)
{
int fx=get_father(x);
int fy=get_father(y);
if(fx!=fy) pr[fx]=fy;
} int main()
{
scanf("%d%d",&n,&m);
int x,y,v;
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&cr[i].x,&cr[i].y,&cr[i].v);
}
sort(cr+,cr+m+,cmp);
memset(pr,,sizeof(pr));
memset(en,,sizeof(en));
for(int i=;i<=n;i++) {pr[i]=i;en[i]=;}
for(int i=;i<=m;i++)
{
x=cr[i].x;
y=cr[i].y;
int fx=get_father(x);
int fy=get_father(y);
if(fx==fy)
{
printf("%d\n",cr[i].v);
return ;
}
if(en[x]==) en[x]=y;
else Union(y,en[x]);
if(en[y]==) en[y]=x;
else Union(x,en[y]);
}
printf("0\n");
return ;
}

【并查集】关押罪犯(BSOJ2809)的更多相关文章

  1. 关押罪犯 and 食物链(并查集)

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

  2. 并查集补集作法 codevs 1069 关押罪犯

    1069 关押罪犯 2010年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解       题目描述 Description ...

  3. NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]

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

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

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

  5. Luogu 1525 【NOIP2010】关押罪犯 (贪心,并查集)

    Luogu 1525 [NOIP2010]关押罪犯 (贪心,并查集) Description S城现有两座监狱,一共关押着N名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨 ...

  6. 洛谷 P1525 【关押罪犯】种类并查集

    题解 P1525 [关押罪犯]:种类并查集 前言: 在数据结构并查集中,种类并查集属于扩展域并查集一类. 比较典型的题目就是:食物链(比本题难一些,有三个种类存在) 首先讲一下本题的贪心,这个是必须要 ...

  7. 【codevs1069】关押罪犯[noip2010](并查集)

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

  8. noip 2010 关押罪犯 二分答案+二分图染色 || 并查集

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

  9. NOIP 2010 关押罪犯 并查集 二分+二分图染色

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

随机推荐

  1. 中小企业 DevOps 从 0 到 1

    原文:http://www.sohu.com/a/145065274_262549 今天主要有四个课题: 先聊一聊 DevOps: 然后跟大家聊一聊运维知识的体系和职业发展: 再是中小企业基于开源的 ...

  2. git 4种对象的理解

    git中有四种基本对象类型,可以说Git的所有操作都是通过这四种对象完成的.下图是<Git版本控制管理>中文第二版的原话,顺便吐槽一下,这本书真的翻译的一般.. 下面说下我的理解吧,首先b ...

  3. mac权限

    mac文件后面出现@权限 去除方法: xattr -c 文件名  目录也可以

  4. background API

    语法: background:bg-color bg-image position/bg-size bg-repeat bg-origin bg-clip bg-attachment initial| ...

  5. 使用 yarn 作为 Npm 的代替方案

    相关传送门: # window 安装包下载https://yarnpkg.com/zh-Hans/docs/install#windows-stable # yarn官方网站 https://yarn ...

  6. killall 命令

    Linux系统中的killall命令用于杀死指定名字的进程(kill processes by name).我们可以使用kill命令杀死指定进程PID的进程,如果要找到我们需要杀死的进程,我们还需要在 ...

  7. File类的源码学习

    File类是Java中IO部分的一个类,用于表示文件或者目录的.关于File类有很多的常规操作这里就不介绍了,来看一下不常规的东西. File英文意思是文件,但是它也可以用来表示目录,文件的概念还是比 ...

  8. linux应用网址

    APUE学习:(十三) [终篇] 一起学 Unix 环境高级编程 (APUE) 之 网络 IPC:套接字 linux应用学习笔记(已列目录供跳转):http://www.cnblogs.com/ggj ...

  9. mysql导出数据库提示警告在GTID模式下面

    [root@db02 tmp]# mysqldump -S /tmp/mysql.sock -A -R --triggers --master-data=2 --single-transaction ...

  10. python 学习2 测试报告

    1. py.test test_class.py  --resultlog=./log.txt 2.生成html格式 py.test test_class.py --html=./report.htm ...