题面描述

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的更多相关文章

  1. 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])$的限制,问从开头开始最多到哪条限制全是有解的. 那么,首先有可二分性,所以 ...

  2. POJ2723 Get Luffy Out解题报告tarjan+2-SAT+二分

    今天看到讲2-SAT比较好的blog,感觉微微的理解了2-SAT 传送门 参考: https://blog.csdn.net/leolin_/article/details/6680144 题意:你有 ...

  3. 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 ...

  4. poj 2723 Get Luffy Out 二分+2-sat

    题目链接 给n个钥匙对, 每个钥匙对里有两个钥匙, 并且只能选择一个. 有m扇门, 每个门上有两个锁, 只要打开其中一个就可以通往下一扇门. 问你最多可以打开多少个门. 对于每个钥匙对, 如果选择了其 ...

  5. HDU - 1816 Get Luffy Out *(二分 + 2-SAT)

    题目大意:有N串钥匙,M对锁.每串钥匙仅仅能选择当中一把.怎样选择,才干使开的锁达到最大(锁仅仅能按顺序一对一对开.仅仅要开了当中一个锁就可以) 解题思路:这题跟HDU - 3715 Go Deepe ...

  6. poj2723 2sat判断解+二分

    典型的2-sat问题,题意:有m个门,每个门上俩把锁,开启其中一把即可,现在给n对钥匙(所有 钥匙编号0123456...2n-1),每对钥匙只能用一把,要求尽可能开门多(按顺序,前max个). 关键 ...

  7. POJ 2723 Get Luffy Out(2-SAT+二分答案)

    Get Luffy Out Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8851   Accepted: 3441 Des ...

  8. Get Luffy Out (poj 2723 二分+2-SAT)

    Language: Default Get Luffy Out Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7969   ...

  9. 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 ...

随机推荐

  1. 高效C++:实现

    本章主要是解决如下问题: 类的声明和定义在什么时候提出 类与类之间的耦合关系如何降低 类型转换怎么正确使用 尽可能延后变量定义式的出现 变量用到时在定义,不要提前定义,防止变量定义而没有使用的情况,因 ...

  2. 015.Nginx重定向

    一 重定向概述 1.1 重定向介绍 重定向(Redirect)指通过各种方法将各种网络请求重新定个方向转到其它位置(如:网页重定向.域名的重定向.路由选择的变化也是对数据报文经由路径的一种重定向). ...

  3. Terminal终端控制台常用操作命令

    新建文件夹和文件 cd .. 返回上一级 md test 新建test文件夹 md d:\test\my d盘下新建文件夹 cd test 进入test文件夹 cd.>cc.txt 新建cc.t ...

  4. web自动化 -- ActionChains()的鼠标操作

    webdriver模块下的ActionChains类 一.两个主要组件 1.实例化  ActionChains() 2.ActionChains(driver).perform() perform() ...

  5. control+B进入layout文件的xml文本编辑模式

    control+B进入layout文件的xml文本编辑模式

  6. flask中的endpoint是什么

    app.view_functions 是一个字典,里面是存储的是 endpoint 与 视图函数的键值对,如果没指名函数视图的endpoint,默认是函数名,而 url_map 是一个列表,里面是ur ...

  7. Python os.ttyname() 方法

    概述 os.ttyname() 方法用于返回一个字符串,它表示与文件描述符fd 关联的终端设备.如果fd 没有与终端设备关联,则引发一个异常.高佣联盟 www.cgewang.com 语法 ttyna ...

  8. 从别人的代码中学习golang系列--03

    这篇博客还是整理从https://github.com/LyricTian/gin-admin 这个项目中学习的golang相关知识. 作者在项目中使用了 github.com/casbin/casb ...

  9. Linux的VMWare中Centos7用户和用户管理三个系统文件(/etc/passwd-shadow-group解读)和批量创建用户user及用户工作环境path

    Linux 用户和用户组管理 用户工作环境PATH Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统. 用 ...

  10. 笨办法学习python3练习代码:argv参数变量与文件操作

    ex15.py 完成ex15.py需要在ex15.py同文件夹目录下面准备一个txt文件(ex15_sample.txt) 执行ex15.py 如: python     ex15.py      e ...