题目描述

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。

思路1:

考虑用二分答案+二分图判断

我们不难想到,a与b有c这么多的矛盾,则可以说a与b间有权重为c的边,这样就构成了有n个顶点m条边的无向图。

将罪犯分配到两个监狱中,不难想到是二分图。

排序罪犯的怒气值c,进行二分查找,对于当前找到的这个怒气值(边)mid,我们将图中比这条mid边权重小或等于的边暂时删去,判断剩下的图能否构成一个二分图,如果构成则当前的这个怒气值mid即为所求,输出结束程序即可,不要忘了如果没有任何冲突事件发生则输出0.

拓展:二分图判断——染色法

从其中一个顶点开始,将跟它邻接的点染成与其不同的颜色,如果邻接的点有相同颜色的,则说明不是二分图,每次用bfs遍历即可

判断代码如下(源自:https://blog.csdn.net/zhangxian___/article/details/73699241):

 #include <queue>
#include <cstring>
#include <iostream>
using namespace std; const int N=;
int color[N],graph[N][N]; //0为白色,1为黑色
bool bfs(int s, int n)
{
queue<int> q;
q.push(s);
color[s]=;
while(!q.empty())
{
int from=q.front();
q.pop();
for(int i=;i<=n;i++)
{
if(graph[from][i]&&color[i]==-)
{
q.push(i);
color[i]=!color[from];//染成不同的颜色
}
if(graph[from][i]&&color[from]==color[i]) return false;//颜色有相同,则不是二分图
}
}
return true;
} int main()
{
int n,m,a,b,i;
memset(color,-,sizeof(color));
cin>>n>>m;
for(i=;i<m;i++)
{
cin>>a>>b;
graph[a][b]=graph[b][a]=;
}
bool flag=false;
for(i=;i<=n;i++)
if(color[i]==-&&!bfs(i,n)) //遍历各个连通分支
{
flag=true;
break;
}
if(flag)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
return ;
}

思路2:

考虑用并查集+贪心思想

这个方法较上面的方法容易理解,贪心地:我们希望怒气值很大的两个罪犯不在同一个监狱,如遇到两个罪犯不得不在一个监狱时,这时候输出的结果即为最大值。

我们按照并查集路径优化的思想,两个监狱各选出一个头子,这样我们在判断两个罪犯是否要放在两个监狱时,只有看看他们之前是否就归附于同一个头子,如果之前两人都归附于同一个监狱的头子,输出就OK,否则安排他俩进两个监狱。

按照怒气值从大到小依次取出两个罪犯,看看他们能否放在两个监狱:

如果能放,必须要满足不归附于同一个头子。

如果不能放,则安排他俩进进不同监狱,然后两个罪犯分别当上两个监狱的头子(即让原来的监狱头子归附于当前a与b)。

 #include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <iostream>
using namespace std;
typedef struct conflict//存储矛盾信息
{
int a,b,c;//a与b有c这么多的矛盾(怒气)
}conflict; int against[]={};//against[i]存储i的敌人
int father[];//记录这个节点的父亲
conflict infermation[];//记录信息数组 bool cmp(conflict x,conflict y)//排序函数
{
return x.c>y.c;
} int find(int x)//寻找x节点的头子(并查集+路径压缩)
{
if(x!=father[x]) father[x]=find(father[x]);
return father[x];
} int main()
{
int n,m;
int i,j;
int x,y;//x为a的祖先,y为b的祖先
//freopen("prison.in","r",stdin);
//freopen("prison.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=;i<=m;i++)//输入信息
{
scanf("%d%d%d",&infermation[i].a,&infermation[i].b,&infermation[i].c);
}
sort(infermation+,infermation+m+,cmp);//按矛盾值从大到小排序结构体
for(i=;i<=n;i++)
{
father[i]=i;//并查集初始化(自己是自己的父亲)
}
for(i=;i<=m;i++)//从大到小取出矛盾值判断
{
if(find(infermation[i].a)==find(infermation[i].b))//如果两个罪犯已经在一个监狱了(他们都归附于同一个头子),肯定是最优值,输出,结束程序
{
printf("%d\n",infermation[i].c);
return ;//直接结束程序
}
if(!against[infermation[i].a])//如果a没有敌人
{
against[infermation[i].a]=infermation[i].b;//那么b归入a的敌人中
}
else
{
father[find(against[infermation[i].a])]=father[infermation[i].b];//否则把b和a的敌人分在一起,即a的敌人头子指向b的父亲
}
if(!against[infermation[i].b])//如果b没有敌人
{
against[infermation[i].b]=infermation[i].a; //那么a归入b的敌人中
}
else
{
father[find(against[infermation[i].b])]=father[infermation[i].a];//否则把a和b的敌人分在一起,即b的敌人头子指向a的父亲
}
}
printf("0\n");//没有冲突找到则输出0
return ;
}

洛谷-关押罪犯-NOIP2010提高组复赛的更多相关文章

  1. 洛谷 P1525 关押罪犯 & [NOIP2010提高组](贪心,种类并查集)

    传送门 解题思路 很显然,为了让最大值最小,肯定就是从大到小枚举,让他们分在两个监狱中,第一个不符合的就是答案. 怎样判断是否在一个监狱中呢? 很显然,就是用种类并查集. 种类并查集的讲解——团伙(很 ...

  2. 洛谷-乘积最大-NOIP2000提高组复赛

    题目描述 Description 今年是国际数学联盟确定的“2000――世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年.在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你 ...

  3. 洛谷-铺地毯-NOIP2011提高组复赛

    题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...

  4. 洛谷 P1525 关押罪犯 NOIp2010提高组 (贪心+并查集)

    题目链接:https://www.luogu.org/problemnew/show/P1525 题目分析 通过分析,我们可以知道,这道题的抽象意义就是把一个带边权的无向图,分成两个点集,使得两个集合 ...

  5. 洛谷-统计数字-NOIP2007提高组复赛

    题目描述 Description 某次科研调查时得到了n个自然数,每个数均不超过1500000000(1.5*10^9).已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照 ...

  6. 洛谷-均分纸牌-NOIP2002提高组复赛

    题目描述 Description 有 N 堆纸牌,编号分别为 1,2,…, N.每堆上有若干张,但纸牌总数必为 N 的倍数.可以在任一堆上取若于张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取的纸 ...

  7. 洛谷-拼数-NOIP1998提高组复赛

    题目描述 Description 设有n个正整数(n≤20),将它们联接成一排,组成一个最大的多位整数. 例如:n=3时,3个整数13,312,343联接成的最大整数为:34331213 又如:n=4 ...

  8. 洛谷 P2196 挖地雷 & [NOIP1996提高组](搜索,记录路径)

    传送门 解题思路 就是暴力!!! 没什么好说的,总之,就是枚举每一个起点,然后暴力算一遍以这个点为起点的所有路径,在算的过程中,只要比目前找到的答案更优,就有可能是最后的答案,于是就把路径更新一遍,保 ...

  9. 洛谷P1082 同余方程 [2012NOIP提高组D2T1] [2017年6月计划 数论06]

    P1082 同余方程 题目描述 求关于 x 的同余方程 ax ≡ 1 (mod b)的最小正整数解. 输入输出格式 输入格式: 输入只有一行,包含两个正整数 a, b,用一个空格隔开. 输出格式: 输 ...

随机推荐

  1. secureCRT linux shell显示中文乱码 解决方法

    引:有没有这样的经历: 1.在shell中直接查看包含中文的文件时,出现一堆火星文,不得不下载下来window看. 2.无法正常的在shell中输入中文. 3.make的时候输出一堆乱码. 以下是查阅 ...

  2. rails 常用方法

    bundle install --without production 不安装production中的gem ./configure && make && sudo m ...

  3. 关于scrollLeft的获取在不同浏览器或相同浏览器的不同版本下的获取

    chrome61向w3c规则靠拢,document.body.scrollLeft获取的值一直为0,需要使用document.documentElement.scrollLeft(或document. ...

  4. 【leetcode刷题笔记】Add Binary

    Given two binary strings, return their sum (also a binary string). For example,a = "11"b = ...

  5. memcached监控脚本

    #!/bin/bash . /etc/init.d/functions |wc -l` -lt ];then action "Memcached Serivce is error." ...

  6. Java+MySql图片数据保存

    之前一直没有做过涉及到图片存储的应用,最近要做的东东涉及到了这个点,就做了一个小的例子算是对图片存储的初试吧! 1.创建表: drop table if exists photo; CREATE TA ...

  7. 51nod1613

    题意:给定n个正面朝上的硬币,每次可以翻转k个硬币,求至少多少次翻转能使之全部反面朝上. 神犇题解 我真的吐槽不能了..这题能做?! 极其复杂的分类讨论..膜拜这位爷.

  8. Codeforces 509F Progress Monitoring:区间dp【根据遍历顺序求树的方案数】

    题目链接:http://codeforces.com/problemset/problem/509/F 题意: 告诉你遍历一棵树的方法,以及遍历节点的顺序a[i],长度为n. 问你这棵树有多少种可能的 ...

  9. 英语发音规则---字母组合oo的发音规律

    英语发音规则---字母组合oo的发音规律 一.总结 一句话总结:在英语单词中,字母组合oo多数读长音/u:/,少数读短音/ʊ/.另外,还有极少数的特殊情况读/ʌ/, 在英语单词中,字母组合oo多数读长 ...

  10. node.js+express+jade系列三:404错误的配置

    1:新建一个404.jade 2:在app.js后面配置如下代码 app.use(function(req, res){        res.render("404", {sta ...