题目链接:https://ac.nowcoder.com/acm/contest/258/C

题目大意:

  略

分析:

  这题是并查集的一个变题,先按积怨值从大到小排序,然后一个一个看能否完全分开,遇到的第一个不能分开的囚犯对(如果强行分开就必然有更高的积怨值出现)就是答案。
  一开始想到的是按监狱数量弄个并查集,后来发现并不行,因为如果要分开一对囚犯,没办法决定谁一定住1号监狱,谁一定住2号监狱。后来试了下用囚犯数量弄并查集,发现也不行,因为没有积怨的才能放一个集合里,比如1和2有积怨不在一起,3和4有积怨不在一起,那1和3,1和4等等就没法确定,那把他们都放不同集合里?不行,因为不在一个集合的可能有积怨可能没积怨。
  让后我就想当选取到i + 1对囚犯时,前i对囚犯必然也形成一张图,这张图可能不是连通的,换句话说,就是包含多个极大联通子图(囚犯小团体),小团体与小团体之间互相没有积怨,因为程序已经选取到了i + 1对囚犯,所以这些小团体内部必然可以两两分开以致于没有积怨。选取其中一个小团体,如果这个极大联通子图没有坏,那必然可以变形成如下形式:
也就是说,肯定可以一刀切。
如果有环,那促成环的这条线的两端必分别属于左右两边:
如果这个时候来了一条边,它的两个端点都在这张图的一边:
那这张图必然怎么切都切不开了。
也就是说,如果第i + 1对囚犯都属于某一个小团体的一边,答案就出来了。
也就是说每名囚犯应该有2个状态i和i',上面的图应该是这样:
于是并查集的长度应该为2n,前n个表示1~n,后n个表示1'~n'。
PS:代码中并没有判断是否在都一边而是直接判断在不在一个集合,这是因为是直接查找的同一边的点,就是没有'的那边,这样直接判断在不在一个集合就可以了。

代码如下:

 #include <bits/stdc++.h>
using namespace std; #define rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define rFor(i,t,s) for (int i = (t); i >= (s); --i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i) #define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl #define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin()) #define ms0(a) memset(a,0,sizeof(a))
#define msI(a) memset(a,inf,sizeof(a)) #define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define mp make_pair
#define pb push_back
#define fi first
#define se second inline int gc(){
static const int BUF = 1e7;
static char buf[BUF], *bg = buf + BUF, *ed = bg; if(bg == ed) fread(bg = buf, , BUF, stdin);
return *bg++;
} inline int ri(){
int x = , f = , c = gc();
for(; c<||c>; f = c=='-'?-:f, c=gc());
for(; c>&&c<; x = x* + c - , c=gc());
return x*f;
} typedef long long LL;
const int maxN = 1e5 + ; struct Edge{
int X, Y, W; Edge() {}
Edge(int x, int y, int w) : X(x), Y(y), W(w) {} bool operator < (const Edge &x) const {
return W > x.W;
}
}; int n, m, ans;
Edge e[maxN];
int f[maxN]; int Find(int x){
while (x != f[x]) x = f[x] = f[f[x]];
return x;
} int main(){
n = ri();
m = ri(); For(i, , m) {
e[i].X = ri();
e[i].Y = ri();
e[i].W = ri();
}
sort(e+, e+m+);
For(i, , n<<) f[i] = i; For(i, , m) {
int x = e[i].X, y = e[i].Y;
x = Find(x);
y = Find(y);
if(x == y) {
ans = e[i].W;
break;
}
f[x] = Find(e[i].Y + n);
f[y] = Find(e[i].X + n);
} printf("%d\n", ans);
return ;
}

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

  1. NOIP2010提高组] CODEVS 1069 关押罪犯(并查集)

    这道这么简单的题目还写了这么久.. 将每个会发生冲突的两人的怒气进行排序,然后从怒气大到小,将两个人放到不同监狱中.假如两人都已经被放置且在同一监狱,这就是答案. ------------------ ...

  2. 洛谷-关押罪犯-NOIP2010提高组复赛

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

  3. 洛谷-机器翻译-NOIP2010提高组复赛

    题目背景 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 题目描述 这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换.对于每个英文单词,软件会先 ...

  4. NOIP2010提高组真题部分整理(没有关押罪犯)

    目录 \(NOIP2010\)提高组真题部分整理 \(T1\)机器翻译: 题目背景: 题目描述: 输入输出格式: 输入输出样例: 说明: 题解: 代码: \(T2\)乌龟棋 题目背景: 题目描述: 输 ...

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

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

  6. noip2010提高组题解

    NOIP2010提高组题解 T1:机器翻译 题目大意:顺序输入n个数,有一个队列容量为m,遇到未出现元素入队,求入队次数. AC做法:直接开1000的队列模拟过程. T2:乌龟棋 题目大意:有长度为n ...

  7. NOIP2010提高组乌龟棋 -SilverN

    题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...

  8. 【题解】NOIP2016提高组 复赛

    [题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...

  9. 【题解】NOIP2015提高组 复赛

    [题解]NOIP2015提高组 复赛 传送门: 神奇的幻方 \([P2615]\) 信息传递 \([P2661]\) 斗地主 \([P2668]\) 跳石头 \([P2678]\) 子串 \([P26 ...

随机推荐

  1. 37.QT-QTSingleApplication-程序只运行一个实例

    QTSingleApplication由Qt官方提供的,用于实现只启动一个实例,并在启动时可以向向另一个实例通信(依赖于QtNetwork模块) QTSingleApplication下载路径:链接: ...

  2. Spring Boot 整合 docker

    一.什么是docker ? 简介 Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs ...

  3. 20190321-HTML基本结构

    目录 1.HTML概念 超文本标记语言 2.HTML版本 HTML HTML5 3.HTML基本结构 基本结构 元素.标签.属性 4.HTML常用标签 内容 1.HTML概念 HTML(HyperTe ...

  4. 前端入门11-JavaScript语法之数组

    声明 本系列文章内容全部梳理自以下几个来源: <JavaScript权威指南> MDN web docs Github:smyhvae/web Github:goddyZhao/Trans ...

  5. charles抓包出现乱码 SSL Proxying not enabled for this host:enable in Proxy Setting,SSL locations

    1.情景:抓包的域名下 全部是unknown,右侧出现了乱码 2.查看unknown的notes里面:SSL Proxying not enabled for this host:enable in ...

  6. Selenium自动化-入门1

    起初写博客是为了妹子学习,现在发现忽略了最基础的Selenium教程,所以:从本博客开始编辑 Selenium 入门知识.(学好Java) Selenium 入门 1:(学好Java) 录制回放,简单 ...

  7. csharp: LocalDataCache.sync

    app.config: <?xml version="1.0" encoding="utf-8" ?> <configuration> ...

  8. iPad----------教你如何查询ipad型号

    1.首先进入苹果官网 找到support    https://support.apple.com 2.找到查询ipad型号的地方  点击Check  coverage for your produc ...

  9. Python枚举类

    Enum可以把一组相关常量定义在一个class中,且class不可变,而且成员可以直接比较. 定义枚举类: from enum import Enum, unique @unique class We ...

  10. ionic获取表单input的值的两种方法

    1.参数传递法 直接在input处使用 #定义参数的name值,注意在ts中参数的类型 html页面: <ion-input type="text" placeholder= ...