https://www.zybuluo.com/ysner/note/1334611

居然开始写水题题解了,noip退役预定

题面

戳我

解析

这道题似乎有三种做法:

并查集

我们知道,如果要求两个人不冲突,它们必须在不同监狱里。
然而总共也只有两个监狱啊。
所以对于一个人来说,要么和另一个人在同一监狱,要么和另一人不在同一监狱。
这种二分图式的排斥关系,其实可以用并查集的补集来表示。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;++i)
#define fq(i,a,b) for(re int i=a;i>=b;--i)
using namespace std;
const int N=1e5+100;
int n,m,f[N];
il int find(re int x){return x==f[x]?x:f[x]=find(f[x]);}
struct dat{int u,v,w;il bool operator < (const dat &o) const {return w>o.w;}}a[N];
il ll gi()
{re ll x=0,t=1;re char ch=getchar();while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();if(ch=='-') t=-1,ch=getchar();while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();return x*t;
}
il void cmax(re int &x,re int y){x=(x>y?x:y);}
int main()
{n=gi();m=gi();fp(i,1,n*2) f[i]=i;fp(i,1,m){re int u=gi(),v=gi(),w=gi();a[i]=(dat){u,v,w};}sort(a+1,a+1+m);fp(i,1,m){re int u=a[i].u,v=a[i].v,w=a[i].w,fu=find(u),fv=find(v);if(fu==fv) return printf("%d\n",w),0;f[fu]=find(v+n);f[fv]=find(u+n);}puts("0");return 0;
}

二分图染色

仔细看看题,你会发现,要求的其实是最小化的最大值。
这种问题可以二分。

于是只连权值大于\(mid\)的边。
然后判断所有边的两端是否能去不同的监狱。
这个可以用二分图染色完成。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<queue>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;++i)
#define fq(i,a,b) for(re int i=a;i>=b;--i)
using namespace std;
const int N=1e5+100;
int n,m,h[N],cnt,col[N],tag;
struct Edge{int to,nxt;}e[N<<1];
struct dat{int u,v,w;il bool operator < (const dat &o) const {return w>o.w;}}a[N];
il void add(re int u,re int v){e[++cnt]=(Edge){v,h[u]};h[u]=cnt;}
il ll gi()
{re ll x=0,t=1;re char ch=getchar();while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();if(ch=='-') t=-1,ch=getchar();while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();return x*t;
}
il void dfs(re int u)
{if(!tag) return;for(re int i=h[u];i+1;i=e[i].nxt){re int v=e[i].to;if(col[v]==-1) col[v]=col[u]^1,dfs(v);else if(col[v]==col[u]) {tag=0;return;}}
}
il int check(re int x)
{memset(h,-1,sizeof(h));cnt=0;memset(col,-1,sizeof(col));fp(i,1,m)if(a[i].w>x) add(a[i].u,a[i].v),add(a[i].v,a[i].u);tag=1;fp(i,1,n) if(col[i]==-1) col[i]=0,dfs(i);return tag;
}
il void cmax(re int &x,re int y){x=(x>y?x:y);}
int main()
{n=gi();m=gi();fp(i,1,m){re int u=gi(),v=gi(),w=gi();a[i]=(dat){u,v,w};}sort(a+1,a+1+m);re int l=0,r=a[1].w,ans=0;while(l<=r){re int mid=l+r>>1;if(check(mid)) ans=mid,r=mid-1;else l=mid+1;}printf("%d\n",ans);return 0;
}

二分图

众所周知,要形成二分图,图中不能有奇环。
所以我们把边按边权排序后,只要一条边加入后形成了奇环,就可以输出答案了。

所以怎么判呢?
判是否形成环可以用并查集,判形成的环是否是奇环当然也可以用并查集。

因为每次连边,我们都是把并差集的根结点相连。
如果在之前根结点已经相连,再连边就会形成环。
环的大小吗,就是两端点分别离根结点的距离之和\(+1\)。(当然不能路径压缩)

所以每次合并时,我们维护一下每个点到其并查集父亲距离的奇偶性。
求环大小时,从两端点分别暴跳父亲即可。

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define re register
#define il inline
#define pc(a) putchar(a)
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
const int N=2e5+100,inf=1e9+100;
int f[N],n,m,dp[N],h[N];
bool vis[N];
ll ans;
struct dat{int u,v,w;bool operator < (const dat &o) const {return w>o.w;}}a[N<<1];
il int find(re int x){while(f[x]^x) x=f[x];return x;}
il int Dis(re int x){re int res=0;while(f[x]^x) res^=dp[x],x=f[x];return res;}
il int gi()
{re int x=0,t=1;re char ch=getchar();while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();if(ch=='-') t=-1,ch=getchar();while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();return x*t;
}
int main()
{n=gi();m=gi();fp(i,1,n) f[i]=i,h[i]=1;fp(i,1,m) a[i].u=gi(),a[i].v=gi(),a[i].w=gi();sort(a+1,a+1+m);fp(i,1,m){re int u=a[i].u,v=a[i].v,fu=find(u),fv=find(v),w=a[i].w;if(fu^fv) dp[fu]^=Dis(u)^Dis(v)^1,f[fu]=fv;else if(Dis(u)^Dis(v)==0) {printf("%d\n",w);return 0;}}puts("0");return 0;
}

转载于:https://www.cnblogs.com/yanshannan/p/9920476.html

noip2010关押罪犯相关推荐

  1. NOIP2010关押罪犯题解(洛谷P1525) (并查集)

    NOIP2010关押罪犯题解(洛谷P1525) (并查集) 日常膜拜dalao:财神万岁!!!!!!!!!!!!!!!!!!!!! 日常凌晨三点水题解..(原谅我中间断更了几天,,马上分班考试了竞赛顾 ...

  2. [NOIP2010]关押罪犯

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

  3. 【题解】[NOIP2010]关押罪犯

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

  4. [NOIP2010]关押罪犯(题解)

    目录 篛箕的自诉 题目分析+代码: 第一种做法(图论+搜索): 第二种做法(并查集,拓展域): 篛箕的自诉 以前的我对你爱搭不理,现在的我对你笔不能提: 传送门 以前学习搜索的时候看到这个题就感觉一定 ...

  5. [NOIP2010]关押罪犯(二分+二分图染色)

    传送门 大意:我们把图分为两部分,使得两部分中的内部边的最大权值最小. 思路:哎,拿到题的时候想了二分图染色,发现不好做,但我没有想到二分,只好最后去骗了一个30分.正确的思路是:首先我们要 去二分最 ...

  6. #洛谷oj:P1525 [NOIP2010 提高组] 关押罪犯

    洛谷oj:P1525 [NOIP2010 提高组] 关押罪犯 #题目描述 #一看很明显是贪心算法 加排序 因为 这个中间最大值的那一对肯定是不会在一起的 从大到小来看 所有点对都尽量不要在一个监狱 # ...

  7. [NOIP2010提高组]关押罪犯

    题目:洛谷P1525.Vijos P1776.codevs1069. 题目大意:有一些罪犯,两个罪犯之间可能会发生冲突,冲突有个影响力,而如果两个罪犯在不同监狱里,就可以避免冲突.现在有两个监狱,要你 ...

  8. 专题突破三之并查集Ⅱ——星球大战,In Touch,方格染色,Junk-Mail Filter,关押罪犯,Silver Woods,Must Be Rectangular!

    文章目录 [JSOI2008]星球大战 In Touch 方格染色 Junk-Mail Filter [NOIP2010 提高组] 关押罪犯 Silver Woods Must Be Rectangu ...

  9. 关押罪犯-并查集、贪心

    题目来源:Acwing 257.关押罪犯&洛谷 P1525 [NOIP2010 提高组] 关押罪犯 思路来源:这里 题目描述 S 城现有两座监狱,一共关押着 N 名罪犯,编号分别为1~N. 他 ...

最新文章

  1. nmap,tcpdump
  2. OpenGL生成的法线贴图并增加光照
  3. 《图说VR入门》——DeepoonVR的大鹏(陀螺仪)枪
  4. barrier相關知識點整理(还没搞完)
  5. 简单的二叉树创建与遍历
  6. Repeater的嵌套
  7. 第一家店开始要做品牌吗?
  8. 跳转微信公众号首页方式
  9. matlab做分数阶差分,分数阶微分方程数值实验MATLAB编码
  10. python中的IO操作
  11. 一个遮罩层怎么遮罩两个图层_遮罩动画只能有两个图层,上面为“遮罩层”,下面为“被遮罩”层。...
  12. iOS自动化部署方案Jenkins Fastlane code.aliyun 蒲公英 appStore
  13. Elasticsearch查询的基本使用
  14. 大一c语言考试题信阳师范学院,zhaodapeng6
  15. 我帮你弄条长虹 | 兄弟姊妹篇
  16. 分析手机拍照发展史,OPPO扮演了不可或缺的角色
  17. 国外的个性化定制站点
  18. java listfile为null_java学习日志---File实例:实现复制整个文件夹、解决listFiles()为null问题...
  19. 平板如何调色? 手把手教你校正iPad屏幕
  20. 苹果手机运行服务器无响应是怎么回事,苹果手机显示无服务状态是什么原因?怎么解决?...

热门文章

  1. Springboot文件上传 百度ocr文字识别提取
  2. 算法之动态规划初步(Java版)
  3. Oracle 查看library cache 解析命中率
  4. [转]DML DDL DCL 语言的区别
  5. Gentoo 安装日记 16(编译内核)
  6. angular点击按钮弹出页面_Axure RP8:如何做出点击按钮切换页面效果?
  7. java 命令 乱码_解决java 命令行乱码的问题
  8. 企业大型网络架构怎么做到零攻击?
  9. 运维基础(1)Nginx
  10. mysql最常用的索引_mysql常用索引