【POJ2723】Get Luffy Out - 二分+2-SAT
题面描述
Ratish is a young man who always dreams of being a hero. One day his friend Luffy was caught by Pirate Arlong. Ratish set off at once to Arlong's island. When he got there, he found the secret place where his friend was kept, but he could not go straight in. He saw a large door in front of him and two locks in the door. Beside the large door, he found a strange rock, on which there were some odd words. The sentences were encrypted. But that was easy for Ratish, an amateur cryptographer. After decrypting all the sentences, Ratish knew the following facts:
Behind the large door, there is a nesting prison, which consists of M floors. Each floor except the deepest one has a door leading to the next floor, and there are two locks in each of these doors. Ratish can pass through a door if he opens either of the two locks in it. There are 2N different types of locks in all. The same type of locks may appear in different doors, and a door may have two locks of the same type. There is only one key that can unlock one type of lock, so there are 2N keys for all the 2N types of locks. These 2N keys were divided into N pairs, and once one key in a pair is used, the other key will disappear and never show up again.
Later, Ratish found N pairs of keys under the rock and a piece of paper recording exactly what kinds of locks are in the M doors. But Ratish doesn't know which floor Luffy is held, so he has to open as many doors as possible. Can you help him to choose N keys to open the maximum number of doors?
题意
给你 n 对钥匙,每对若用了其中一把,另一把就不能用。有 m 扇门,每扇门可以由给定的两把钥匙中的任意一把打开,问最多能打开多少扇门。
思路
其实可以不用二分,但二分跑的快些。
二分答案,对于每对钥匙 \(a\) 和 \(b\),\(a\) 用了 \(b\) 就不能用(\(a \rightarrow \neg b\)),\(b\) 用了 \(a\) 就不能用(\(b \rightarrow \neg a\))。
对于每扇门的 \(a\) 和 \(b\),不用 \(a\) 打开就必须用 \(b\) 打开(\(\neg a \rightarrow b\)),不用 \(b\) 打开就必须用 \(a\) 打开(\(\neg b \rightarrow a\))。
所以建个图,跑个 2-SAT 就好啦
代码
/************************************************
*Author : lrj124
*Created Time : 2019.11.10.20:21
*Mail : 1584634848@qq.com
*Problem : poj2723
************************************************/
#include <algorithm>
#include <cstdio>
#include <vector>
#include <stack>
using namespace std;
const int maxn = 10000 + 10;
int n,m,low[maxn],dfn[maxn],scc[maxn],scccnt,ind;
pair<int,int> key[maxn],door[maxn];
vector<int> edge[maxn];
bool vis[maxn];
stack<int> s;
inline void tarjan(int now) {
dfn[now] = low[now] = ++ind;
vis[now] = true,s.push(now);
for (size_t i = 0;i < edge[now].size();i++) {
int to = edge[now][i];
if (!dfn[to]) {
tarjan(to);
low[now] = min(low[now],low[to]);
} else if (vis[to]) low[now] = min(low[now],dfn[to]);
}
if (dfn[now] == low[now]) {
scc[now] = ++scccnt;
for (;s.top() ^ now;vis[s.top()] = false,s.pop()) scc[s.top()] = scccnt;
vis[now] = false,s.pop();
}
}
inline bool check(int mid) {
ind = scccnt = 0;
for (int i = 1;i <= 4*n;i++) edge[i].clear(),low[i] = dfn[i] = 0;
for (int i = 1;i <= n;i++) {
edge[key[i].first].push_back(key[i].second+2*n);
edge[key[i].second].push_back(key[i].first+2*n);
}
for (int i = 1;i <= mid;i++) {
edge[door[i].first+2*n].push_back(door[i].second);
edge[door[i].second+2*n].push_back(door[i].first);
}
for (int i = 1;i <= 4*n;i++) if (!dfn[i]) tarjan(i);
for (int i = 1;i <= 2*n;i++) if (scc[i] == scc[i+2*n]) return false;
return true;
}
int main() {
// freopen("poj2723.in","r",stdin);
// freopen("poj2723.out","w",stdout);
for (;scanf("%d%d",&n,&m),n && m;) {
for (int i = 1,x,y;i <= n;i++) {
scanf("%d%d",&x,&y); x++,y++;
key[i] = make_pair(x,y);
}
for (int i = 1,x,y;i <= m;i++) {
scanf("%d%d",&x,&y); x++,y++;
door[i] = make_pair(x,y);
}
int l = 0,r = m,ans;
for (int mid;l <= r;check(mid = l+r>>1) ? l = mid+1,ans = mid : r = mid-1);
printf("%d\n",ans);
}
return 0;
}
【POJ2723】Get Luffy Out - 二分+2-SAT的更多相关文章
- hdu3715 Go Deeper[二分+2-SAT]/poj2723 Get Luffy Out[二分+2-SAT]
这题转化一下题意就是给一堆形如$a_i + a_j \ne c\quad (a_i\in [0,1],c\in [0,2])$的限制,问从开头开始最多到哪条限制全是有解的. 那么,首先有可二分性,所以 ...
- POJ2723 Get Luffy Out解题报告tarjan+2-SAT+二分
今天看到讲2-SAT比较好的blog,感觉微微的理解了2-SAT 传送门 参考: https://blog.csdn.net/leolin_/article/details/6680144 题意:你有 ...
- POJ2723 Get Luffy Out 【2-sat】
题目 Ratish is a young man who always dreams of being a hero. One day his friend Luffy was caught by P ...
- poj 2723 Get Luffy Out 二分+2-sat
题目链接 给n个钥匙对, 每个钥匙对里有两个钥匙, 并且只能选择一个. 有m扇门, 每个门上有两个锁, 只要打开其中一个就可以通往下一扇门. 问你最多可以打开多少个门. 对于每个钥匙对, 如果选择了其 ...
- HDU - 1816 Get Luffy Out *(二分 + 2-SAT)
题目大意:有N串钥匙,M对锁.每串钥匙仅仅能选择当中一把.怎样选择,才干使开的锁达到最大(锁仅仅能按顺序一对一对开.仅仅要开了当中一个锁就可以) 解题思路:这题跟HDU - 3715 Go Deepe ...
- poj2723 2sat判断解+二分
典型的2-sat问题,题意:有m个门,每个门上俩把锁,开启其中一把即可,现在给n对钥匙(所有 钥匙编号0123456...2n-1),每对钥匙只能用一把,要求尽可能开门多(按顺序,前max个). 关键 ...
- POJ 2723 Get Luffy Out(2-SAT+二分答案)
Get Luffy Out Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8851 Accepted: 3441 Des ...
- Get Luffy Out (poj 2723 二分+2-SAT)
Language: Default Get Luffy Out Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7969 ...
- PKU-2723 Get Luffy Out(2-SAT+二分)
Get Luffy Out 题目链接 Ratish is a young man who always dreams of being a hero. One day his friend Luffy ...
随机推荐
- Python 正则表达式简单了解
match 从字符串的开始匹配 如果开头不符合要求 就会报错 search 用字符串里的每一个元素 去匹配找的元素 1.匹配单个字符 \d 数字 \D 非数字 . 匹配任意字符 除了\n [] ...
- (int) 与 Convert.ToInt32()
((xEnd - xStart) / newSize) + 1 = 172.99999999 int Width = (int)((xEnd - xStart) / newSize) + 1; = ...
- 如何在sed中使用变量,两种方法
第一 在sed条件中是不认识变量取值的 sed '/$x/d' test 所以要想它能够识别变量 sed "/$x/d/" test 方法简单就是把"单引号"变 ...
- Spring Data JPA根据属性名查询
https://blog.csdn.net/chengqiuming/article/details/82528961
- JVM 学习笔记记录
JVM 学习笔记记录 Sun JDK 监控和故障处理工具 名称 主要作用 jps JVM Process Status Tool, 显示指定系统内所有的HotSpot虚拟机进程 jstat JVM S ...
- Flutter中的绘图(Canvas&CustomPaint)API
本文是Flutter中Canvas和CustomPaint API的使用实例. 首先看一下我们要实现的效果: 结合动图演示,列出最终目标如下: 在程序运行后,显示一个小球: 每次程序启动后,小球的样式 ...
- 10-9 重要的内置函数(zip、filter、map、sorted)
reverse----reversed l = [1,2,3,4,5,6] l.reverse() #不会保留原列表 print(l) l =[1,2,3,4,5,6] l2 = reversed(l ...
- Python os.statvfs() 方法
概述 os.statvfs() 方法用于返回包含文件描述符fd的文件的文件系统的信息.高佣联盟 www.cgewang.com 语法 statvfs()方法语法格式如下: os.statvfs([pa ...
- PHP xml_parser_set_option() 函数
定义和用法 xml_parser_set_option() 函数为 XML 解析设置选项.高佣联盟 www.cgewang.com 如果成功,该函数则返回 TRUE.如果失败,则返回 FALSE. 语 ...
- 4.3 省选模拟赛 序列游戏 dp
可以发现 某一段被删除后状态难以表示 也难以链接起来. 考虑暴力 有40分的状压dp 暴力存状态 然后枚举转移即可.最后注意和f[0]这个状态取max 不然一分都没有. const int MAXN= ...