题目描述

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、第一种思路是用并查集的补集,当然也可以带偏移量的并查集,此处只提拱并查集的补集做法。首先先将边权排序,之后从大到小,将两个罪犯分别与另一个罪犯的补集合并,相当于在不同的监狱。

#include<bits/stdc++.h>
using namespace std;
const int maxn=100005;
int fa[maxn*2],n,m;
struct criminal {
int fir,sec,ang;
} cri[maxn];
int find(int x) {
if(x==fa[x]) return x;
return fa[x]=find(fa[x]);
}
int cmp(criminal x,criminal y) {
return x.ang>y.ang;
}
int main() {
scanf("%d%d",&n,&m);
for(register int i=1; i<=n*2; i++) fa[i]=i;
for(register int i=1; i<=m; i++)
scanf("%d%d%d",&cri[i].fir,&cri[i].sec,&cri[i].ang);
sort(1+cri,1+cri+m,cmp);
for(register int i=1; i<=m; i++) {
if(find(cri[i].fir)==find(cri[i].sec)) {
printf("%d",cri[i].ang);
return 0;
} else {
fa[find(cri[i].fir)]=find(cri[i].sec+n);
fa[find(cri[i].sec)]=find(cri[i].fir+n);
}
}
printf("0");
return 0;
}

2、第二组做法是二分答案+二分图染色,首先排序,然后二分答案罪犯的怒气值的数组下标,之后将这个怒气值以上的用无向图连边,最后染色判断是否合法。

#include<bits/stdc++.h>
#define mmp memset
using namespace std;
const int maxn = 100005;
int n,m,head[maxn],cnt,ans,col[maxn];
bool flag;
struct CRIME {
int a,b,ang;
} cri[maxn];
struct Edge {
int next,to;
} edge[maxn*2];
inline bool cmp(CRIME a,CRIME b) {
return a.ang>b.ang;
}
inline bool dfs(int x,int color) { //dfs染色。
col[x]=color;
for(register int i=head[x]; i!=-1; i=edge[i].next) {
int u=edge[i].to;
if(col[u]==color) flag=false;
else if(!col[u])
dfs(u,3-color);
}
}
inline bool judge(int x) { //判断是否合法。
for(register int i=1; i<x; i++) {
if(!col[i]) {
flag=true;
dfs(i,1);
if(flag==false)
return false;
}
}
return true;
}
inline void add(int bg,int ed) {
edge[++cnt].to=ed;
edge[cnt].next=head[bg];
head[bg]=cnt;
}
inline void build(int L,int R) { //二分答案
if(L==m+1) ans=0; //如果最低怒气值仍然满足染色,说明不会发生冲突。
if(L>=R) return;
cnt=0;
mmp(col,0,sizeof(col));
mmp(head,-1,sizeof(head));
int mid=(L+R)>>1;
for(register int i=1; i<mid; i++) {
add(cri[i].a,cri[i].b);
add(cri[i].b,cri[i].a);
}
if(judge(mid)) {
ans=cri[mid].ang;
build(mid+1,R);
} else
build(L,mid);
}
int main() {
scanf("%d%d",&n,&m);
for(register int i=1; i<=m; i++)
scanf("%d%d%d",&cri[i].a,&cri[i].b,&cri[i].ang);
sort(cri+1,cri+1+m,cmp);
build(1,m+1); //m+1代表不会发生冲突。
printf("%d",ans);
}

最新文章

  1. 《Java程序设计与数据结构教程(第二版)》学习指导
  2. HTML标签显示在页面上
  3. PHP 缩放图片
  4. Java 7 Concurrency Cookbook 翻译 第一章 线程管理之五
  5. cpu和memory性能监控
  6. 实用工具推荐(Live Writer)(2015年05月26日)
  7. discuz论坛很给力
  8. springMVC工作原理图
  9. 服务器CPU使用率高的原因分析与解决办法
  10. iOS开发手记 - iOS9.3 UINavigationController添加后不显示storyboard中viewcontroller里的控件的解决方法
  11. 玩sdr的朋友们,在rtl_tcp时,记得调整rtl_AGC和tuner_AGC啊
  12. Mirantis OpenStack 8.0 版本
  13. MySQL 索引的使用
  14. Index Scans 索引扫描
  15. Vue表单控件绑定
  16. Ios App上传步骤
  17. [Active Learning] Multi-Criteria-based Active Learning
  18. 《linux 必读》
  19. 吴恩达机器学习笔记13-正规方程(Normal Equation)
  20. Rifidi

热门文章

  1. jQuery函数API,各版本新特性汇总
  2. ArcGIS Runtime SDK for .NET (Quartz Beta)之连接ArcGIS Portal
  3. C++ placement new与内存池
  4. php自带函数大全
  5. iframe调用页面中的局部部分
  6. vue入门例子
  7. 判断是否英文字母或数字的C#正则表达式
  8. TP5截取部分字符串
  9. 转 Nginx Access Log日志统计分析常用命令
  10. Rabbitmq的延时队列的使用