题目链接: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. [Redis] redis的设计与实现-对象系统

    1.redis并没有直接使用前面的数据结构实现键值对数据库,而是基于数据结构创建了一个对象系统,字符串对象/列表对象/哈希对象/集合对象/有序集合对象都用到了至少一种前面的数据结构2.针对不同的使用场 ...

  2. 30.C++复习篇

    本章学习内容: 1.const 2.指针const 3.inline内联函数 4.函数重载 5.extern “C” 6.new/delete声明与释放 7.namespace命名空间 8.C++中的 ...

  3. Guava Cache 本地缓存组件浅析

    cache组件中核心的类和接口列举如下: 接口: Cache 本地缓存的顶级接口,提供一些对缓存进行get,put的方法,以及获取缓存统计数据的方法等. LoadingCache 继承了Cache接口 ...

  4. Dynamics 365 POA表记录的查询

    微软动态CRM专家罗勇 ,回复313或者20190311可方便获取本文,同时可以在第一间得到我发布的最新博文信息,follow me!我的网站是 www.luoyong.me . PrincipalO ...

  5. 微信小程序下拉刷新和上拉加载的实现

    一: 下拉刷新 下拉刷新两个步骤就能实现. 1.在要实现下拉刷新的页面的json配置文件里面加上 "enablePullDownRefresh": true, //开启下拉刷新 & ...

  6. Linux内存描述之内存页面page--Linux内存管理(四)

    1 Linux如何描述物理内存 Linux把物理内存划分为三个层次来管理 层次 描述 存储节点(Node) CPU被划分为多个节点(node), 内存则被分簇, 每个CPU对应一个本地物理内存, 即一 ...

  7. c/c++ 多线程 参数传递

    多线程 参数传递 1,值传递,拷贝一份新的给新的线程.线程1中有个int变量a,在线程1中启动线程2,参数是a的值,这时就会拷贝a,线程1和线程2不共享a. 2,引用传递,不拷贝一份新的给新的线程.线 ...

  8. jQuery中 对标签元素操作(2)

    一.属性操作 1.获取属性和设置属性 例如下jQuery代码: var $para=$("p");           //获取<p>节点 var p_txt=$par ...

  9. 持续代码质量管理-SonarQube-7.3简单使用

    安装了SonarQube以及Sonar Scanner之后,就需要那代码检测了.当然为了方便我们使用已有现成的demo,知道到对应的git地址下载即可. 1. sonar-examples下载 htt ...

  10. CentOS7.2重置root密码的处理方法

    第一个里程碑 --在启动GRUB菜单中选择编辑选项,按键 "e" 进入编辑; 第二个里程碑 -- 大约在第16行找到 "ro" 将 "ro" ...