题目描述

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. rails member collection

    resources :theses do resources :document do get :download, :on => :member end end <a class=&qu ...

  2. HDU - 1800 Flying to the Mars 【贪心】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1800 题意 给出N个人的 level 然后 高的level 的 人 是可以携带 比他低level 的人 ...

  3. Oracle数据库体系结构(6)数据库归档重做日志文件管理

    归档重做日志文件的概念和选择 Oracle数据库能够把已经写满了的重做日志文件保存到一个或多个指定的离线位置,这种保存的文件为归档重做日志文件.通常情况下一个归档重做日志时一个被LGWR写满的重做日志 ...

  4. flex 坐标系

    全局坐标(舞台坐标)  本地坐标 内容坐标系  地图坐标(MapPoint) flash和flex针对不同的目的,提供了3种不同的坐标系 全局的就是(stage级别的) 本地坐标系(组件级别的) 内容 ...

  5. table-cell笔记

    display:table-cell可将元素设为类似于table的td一样的布局,在垂直居中.两行自适应布局.等高布局下有很高的利用价值 详见: http://www.zhangxinxu.com/w ...

  6. 在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务【转】

    本文转载自:http://blog.csdn.net/luoshengyang/article/details/6578352 在数字科技日新月异的今天,软件和硬件的完美结合,造就了智能移动设备的流行 ...

  7. docker仓库及数据卷

    docker help rmi, 删除本地镜像 docker run -it --name=centos centos:latest /bin/sh  --name的选项可以方便我们以后引用此imag ...

  8. spring boot: Bean的初始化和销毁 (一般注入说明(三) AnnotationConfigApplicationContext容器 JSR250注解)

    import org.springframework.context.annotation.AnnotationConfigApplicationContext; 使用AnnotationConfig ...

  9. 分享知识-快乐自己:Linux下安装 erlang 及 RabbitmMQ

    Linux下安装 erlang 及 RabbitmMQ: 下载地址一  下载地址二 下载地址三 安装依赖: yum install ncurses-devel 安装 erlang: 1):下载Erla ...

  10. Linux-tcpdump command

    简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者的定义对网络上的数据包进行截获的包分析工具. tcpdump可以将网络中传送的数据包的 ...