POJ 2723 Get Luffy Out【二分+2-sat】
题意:已知有 2*n把钥匙,这些钥匙两两一组,每组只能用其中的一把钥匙,有 m 个门,每个门上有两把锁,只要有一把锁被打开门就可以被打开,
一个门上可能是两把相同的锁,不同的门上也有可能有相同的锁,给出门的顺序,问最多可以打开多少扇门。
分析: 每种钥匙都有两种状态,用 or 不用,
kn = 2*n
i 表示 第 i 把钥匙被用,i + kn 表示 不用第 i 把钥匙,
在给出的要是分组中的 i , j
连边 i - > j + kn
j - > i + kn
表示 如果用 i 钥匙则 j 钥匙不能用,如果用 j 钥匙则 i 钥匙不能用
2 分枚举要开的前 k 个门,对于每个门上的两把锁 i , j
连边 i + kn - > j
j + kn - > i
表示如果不开锁 i ,则必须开锁 j,如果不开锁 j,则必须开锁 i,
如果枚举的k个门中没有冲突,则该情况符合。
#include<stdio.h> #include<string.h> #include<math.h> #define maxn 5000 #define clr(x)memset(x,0,sizeof(x)) #define min(a,b)(a)<(b)?(a):(b) struct node {int to,next; }e[1000000]; int tot; int head[maxn]; void add(int s,int t) {e[tot].to=t;e[tot].next=head[s];head[s]=tot++; } int ti,sn,top; int dfn[maxn]; int low[maxn]; int ins[maxn]; int sta[maxn]; int col[maxn]; void tarjan(int u) {dfn[u]=low[u]=++ti;sta[++top]=u;ins[u]=1;int i,k;for(i=head[u];i;i=e[i].next){k=e[i].to;if(dfn[k]==0){tarjan(k);low[u]=min(low[u],low[k]);}else if(ins[k])low[u]=min(low[u],dfn[k]);}if(dfn[u]==low[u]){sn++;do{k=sta[top--];ins[k]=0;col[k]=sn;}while(k!=u);} } struct door {int lock1,lock2; }d[(1<<11)+10],key[maxn]; int kn,n; bool ok(int tm) {int i;int res=0;tot=1;clr(head);for(i=0;i<n;i++){add(key[i].lock1,key[i].lock2+kn);add(key[i].lock2,key[i].lock1+kn);}for(i=1;i<=tm;i++){add(d[i].lock1+kn,d[i].lock2);add(d[i].lock2+kn,d[i].lock1);}top=sn=ti=0;clr(dfn);for(i=0;i<kn;i++)if(!dfn[i])tarjan(i);for(i=0;i<n;i++)if(col[i]==col[i+kn]) return 0;return 1; } int main() {int m;while(scanf("%d%d",&n,&m),n||m){kn=n*2;int a,b,i,j;for(i=0;i<n;i++)scanf("%d%d",&key[i].lock1,&key[i].lock2);j=n;for(i=1;i<=m;i++)scanf("%d%d",&d[i].lock1,&d[i].lock2);int l=1,r=m;int mid;int res=0;while(l<=r){mid=(l+r)>>1;if(ok(mid)){res=mid;l=mid+1;}else r=mid-1;}printf("%d\n",res);}return 0; }
转载于:https://www.cnblogs.com/dream-wind/archive/2012/10/01/2709673.html
POJ 2723 Get Luffy Out【二分+2-sat】相关推荐
- HDU 1816, POJ 2723 Get Luffy Out(2-sat)
HDU 1816, POJ 2723 Get Luffy Out 题目链接 题意:N串钥匙.每串2把,仅仅能选一把.然后有n个大门,每一个门有两个锁,开了一个就能通过,问选一些钥匙,最多能通过多少个门 ...
- ACM POJ 2723 Get Luffy Out(2-SAT入门)
题目链接:http://poj.org/problem?id=2723 [题目大意] 有2n把钥匙,分成2组,给你每组的钥匙信息,并且每组的钥匙只能用一个. 有m个门,每个门有2个锁,只要打开一个锁这 ...
- hdu1816 + POJ 2723开锁(二分+2sat)
题意: 有m层门,我们在最外层,我们要一层一层的进,每一层上有两把锁,我们只要开启其中的一把们就会开,我们有n组钥匙,每组两把,我们只能用其中的一把,用完后第二把瞬间就会消失,问你最多能开到 ...
- 【POJ 3273】 Monthly Expense (二分)
[POJ 3273] Monthly Expense (二分) 一个农民有块地 他列了个计划表 每天要花多少钱管理 但他想用m个月来管理 就想把这个计划表切割成m个月来完毕 想知道每一个月最少花费多少 ...
- POJ 3258 River Hopscotch (二分)
题目地址:POJ 3258 水题.二分距离,判断是否可行.需要注意的是最后一个,因为最后一个是没法移除的,所以还要倒着判断一下. 代码如下: #include <iostream> #in ...
- POJ 2112 Optimal Milking(二分+最大流)
POJ 2112 Optimal Milking 题目链接 题意:给定一些机器和奶牛,在给定距离矩阵,(不在对角线上为0的值代表不可达),每一个机器能容纳m个奶牛.问全部奶牛都能挤上奶,那么走的距离最 ...
- poj 1905 Expanding Rods(二分)
题目:http://poj.org/problem?id=1905 题意:看图就明白了... 杆原长为L,受热膨胀弯曲后的长度为 L'=(1+n*C)*L,求中心的移动的距离h: 思路:推出两个公式: ...
- poj 3258 River Hopscotch 【二分】
题目真是不好读,大意例如以下(知道题意就非常好解了) 大致题意: 一条河长度为 L,河的起点(Start)和终点(End)分别有2块石头,S到E的距离就是L. 河中有n块石头,每块石头到S都有唯一的距 ...
- (poj)1064 Cable master 二分+精度
题目链接:http://poj.org/problem?id=1064 DescriptionInhabitants of the Wonderland have decided to hold a ...
最新文章
- python新手之一环境安装
- 8_Markdown和LaTex的使用中的一些小技巧
- Google的AI模型是如何做A/B Test的
- vb.net播放avi动画
- 2009年岁末年总结
- 高德地图-2D地图下区域遮掩(只显示固定区域里的内容)
- 部分Dell 740 不支持 Xen Server?
- 后缀数组 --- HDU 3518 Boring counting
- linux自定义开机启动服务和chkconfig使用方法
- vue3.0 音频插件(vue-aplayer)
- ECharts模拟百度迁徙实例
- 01 LeNet-5论文笔记-Gradient-Based Learning Applied to Document Recognition
- jQuery blockUI 使用详解
- MySQL Replication 梳理详解
- 美的发布行业首支说唱MV,打造懂年轻人的美的微晶冰箱
- 计算机毕业设计(附源码)python众筹平台
- 自动驾驶Apollo安装步骤
- Manifest基本
- C#的多线程机制初探 (引自 http://www.daima.com.cn/info/234.htm ,在此感谢原作者)
- 搜狗输入法更换字体与皮肤
热门文章
- 任正非亲自指导下拍的视频,事关中国的未来
- G20国家科技竞争力大盘点,中国科研创新表现突出,人工智能变道超车
- 儿子转眼就长大:Hinton、LeCun、Bengio 口述神经网络简史
- Clubhouse 本土化之后干得过“顶流”抖音快手吗? | 极客视频
- Linux--Ubuntu12.04下安装JDK
- Windows上安装AD域控制器注意事项及常见问题处理办法
- 新加坡广告科技公司AdAsia Holdings获1200万美元A轮融资
- 基于 CODING 轻松搞定持续集成
- Node.js模拟发起http请求从异步转同步的5种方法
- Python高级特性——切片(Slice)