传送门

分析:

并查集:

第一步先将所有矛盾从大至小排序,显然先将矛盾值大的分成两部分会更优。

普通的并查集都只能快速合并两个元素至同一集合,却不能将两个元素分至不同集合。

对于将很多数分成两个集合,并给出两数存在的矛盾关系(A和B不能在一集合),普通并查集无法解决。

考虑见每个元素拆成两个点,拆出来的点是它的对立点(i+n),如果要把A和B分至不同集合,就连边 A->B+n,B->A+n(假设先不压缩路径),也就是说:将A与B的对立点分至一个集合 \(\Leftrightarrow\) 将A与B分至不同集合。当然这种思路只能解决分成两部分的情况。

二分+二分图染色

其实就是要求把有矛盾的分到不同组里,于是可以使用二分图染色。先排序,然后二分不能满足的第一个位置,将前面的矛盾关系进行二分图染色,如果然不成功(相邻节点颜色相同),那么更新答案。注意二分图染色要对每个未染色的点都染一次,因为建出来的图可能不联通。

code

并查集:

#include<bits/stdc++.h>
using namespace std;
const int N = 2e4 + 50, M = 1e5 + 50;
int n, m, anc[N * 2];
struct node{
int x, y, w;
inline bool operator < (const node &b) const{
return w > b.w;
}
}edge[M];
inline int getAnc(int x){return x == anc[x] ? x : (anc[x] = getAnc(anc[x]));}
int main(){
freopen("h.in", "r", stdin);
scanf("%d%d", &n, &m);
for(int i = 1; i <= 2 * n; i++) anc[i] = i;
for(int i = 1; i <= m; i++)scanf("%d%d%d", &edge[i].x, &edge[i].y, &edge[i].w);
sort(edge + 1, edge + m + 1);
for(int i = 1; i <= m; i++){
int fx = getAnc(edge[i].x), fy = getAnc(edge[i].y);
if(fx == fy){
printf("%d\n", edge[i].w);
return 0;
}
else{
anc[fx] = getAnc(edge[i].y + n);
anc[fy] = getAnc(edge[i].x + n);
}
}
printf("0");
return 0;
}

二分+二分图染色:

#include<bits/stdc++.h>
using namespace std;
const int N = 2e4 + 40, M = 1e5 + 50;
int n, m, col[N];
vector<int> G[N];
struct State {
int u, c, f;
State() {}
State(int _u, int _c, int _f):u(_u), c(_c), f(_f) {}
};
queue<State> que;
struct node {
int a, b, c;
inline bool operator < (const node &g) const {
return c > g.c;
}
} item[M]; inline bool BiCheck(int mid) {
memset(col, -1, sizeof(int) * (n + 5));
while(!que.empty()) que.pop();
for(int i = 1; i <= n; i++) G[i].clear();
for(int i = 1; i <= mid; i++) {
G[item[i].a].push_back(item[i].b);
G[item[i].b].push_back(item[i].a);
} for(int i = 1; i <= n; i++){
if(col[i] == -1){
col[i] = 0;
que.push(State(i, 0, 0));
while(!que.empty()) {
State t = que.front();
que.pop();
int u = t.u, c = t.c, f = t.f;
for(int e = G[u].size() - 1; e >= 0; e--) {
int v = G[u][e];
if(v == f) continue;
if(col[v] != -1) {
if(col[v] == c) return false;
else continue;
} else col[v] = c ^ 1, que.push(State(v, c ^ 1, u));
}
}
} }
return true;
} int main() {
freopen("h.in", "r", stdin);
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++) scanf("%d%d%d", &item[i].a, &item[i].b, &item[i].c);
sort(item + 1, item + m + 1); int l = 1, r = m, ans = 0;
while(l <= r) {
int mid = l + r >> 1;
if(!BiCheck(mid)) ans = item[mid].c, r = mid - 1;
else l = mid + 1;
}
printf("%d", ans);
return 0;
}

LUOGU 1525 关押罪犯 - 并查集拆点(对立点) / 二分+二分图染色的更多相关文章

  1. NOIP 2010 关押罪犯 并查集 二分+二分图染色

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

  2. Luogu P1525 [NOIp2010提高组]关押罪犯 | 并查集

    题目链接 这一道题,我用了并查集来做.在此题中,并查集的作用就是:将同一个监狱里的罪犯合并到一起. 思路:将每对罪犯之间的怨气值从大到小排序,再依次把他们分到不同的两个监狱里,当发现这一对罪犯已经在同 ...

  3. NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]

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

  4. 洛谷P1525关押罪犯——并查集

    题目:https://www.luogu.org/problemnew/show/P1525 并查集+贪心,从大到小排序,将二人分在不同房间,找到第一个不满足的即为答案. 代码如下: #include ...

  5. [noip2010]关押罪犯 并查集

    第一次看的时候想到了并查集,但是不知道怎么实现: 标解,f[i]表示i所属的集合,用f[i+n]表示i所属集合的补集,实现的很巧妙,可以当成一个使用并查集的巧妙应用: #include<iost ...

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

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

  7. P1525 关押罪犯 并查集

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

  8. luogu1525 [NOIp2011]关押罪犯 (并查集)

    先从大到小排序,看到哪个的时候安排不开了 给每个人拆成两个,如果x和y有矛盾,就给x和y‘.y和x’连边:如果a和b(或a'和b')在同一个集合里,说明他们一定要在同一个监狱里. #include&l ...

  9. 关押罪犯 - 并查集&优先队列

    题目地址:http://www.51cpc.com/web/problem.php?id=4261 Summarize: 此题最巧妙的是“敌人的敌人就是朋友!”,故需先将敌对关系放入优先队列,按怨恨值 ...

随机推荐

  1. ArcGIS 10 影像、栅格数据格式批量转换

    转自原文 ArcGIS 10 影像.栅格数据格式批量转换 在做三维场景的时候,经常会涉及多种不同格式DEM数据或者影像的转换,如ASCII.GRID.IMG.TIFF等等,遇到大数据量时,我们就需要批 ...

  2. IOS开发UI基础--数据刷新

    IOS开发UI基础--数据刷新 cell的数据刷新包括下面几个方面 加入数据 删除数据 更改数据 全局刷新方法(最经常使用) [self.tableView reloadData]; // 屏幕上的全 ...

  3. 怎样将OpenStack部署到Hadoop

    随着信息时代的快速发展,大数据技术和私有云环境都非常实用;只是,假设将两者结合在一起.企业会获得巨大的利润.虽然结合两者会让环境变得更复杂.企业仍然能够看到将 OpenStack 私有云和 Apach ...

  4. java list 容器的ConcurrentModificationException

    java中的很多容器在遍历的同时进行修改里面的元素都会ConcurrentModificationException,包括多线程情况和单线程的情况.多线程的情况就用说了,单线程出现这个异常一般是遍历( ...

  5. hashlib —— Python 的 md5 和 sha1 加密

    python的md5和sha1加密 0. md5 与 sha1 MD5 的全称是 Message-Digest Algorithm 5(信息-摘要算法).128 位长度.目前 MD5 是一种不可逆算法 ...

  6. python缩进报错

    1.这个错误应该已经好久了:也应该熟悉了才对 IndentationError: unexpected indent python 缩进错误:意外缩进Python 但今天的问题有点特殊,我想在程序中间 ...

  7. Python 极简教程(九)元组 tuple

    元组(tuple)是 Python 中的一种序列.和列表类似,但是元组不可变. 也就是说元组一旦声明后,值就不能再改变.我们先来看看元组的样式: >>> t = () # 空元组 & ...

  8. HDOJ 5409 CRB and Graph 无向图缩块

    无向图缩块后,以n所在的块为根节点,dp找每块中的最大值. 对于每一个桥的答案为两块中的较小的最大值和较小的最大值加1 CRB and Graph Time Limit: 8000/4000 MS ( ...

  9. 在 Windows 10 x64 上安装及使用 ab 工具的流程

    本文转自:www.shuijingwanwq.com/2017/04/18/1568/ 1.基于AB测试工具进行高并发情形下的模拟测试,打开:http://httpd.apache.org/docs/ ...

  10. Redis笔记---set

    1.redis set的介绍 集合中的数据是不重复且没有顺序,集合类型和列表类型的对比. 集合类型:存储的是的是最多2的32次方减一个字符串,数据是没有顺序的,但是数据是唯一的 列表类型:最多存储内容 ...