题面描述

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. JavaScript经典实例(浏览器事件)

    跨浏览器事件 1.跨浏览器添加事件 function addEvent(obj,type,fn){ if(obj.addEventListener){ obj.addEventListener(typ ...

  2. Linux指令,更新中

    Linux指令 ls 列举文件. ls *.txt:列举所有txt后缀的文件夹. touch 创建文件. $ touch asd.txt fgh.txt $ touch love{1..10}shiy ...

  3. 利用python实现平稳时间序列的建模方式

    一.平稳序列建模步骤 假如某个观察值序列通过序列预处理可以判定为平稳非白噪声序列,就可以利用ARMA模型对该序列进行建模.建模的基本步骤如下: (1)求出该观察值序列的样本自相关系数(ACF)和样本偏 ...

  4. UUID字符串使用

    UUID字符串使用 1.可以生成唯一的字符串标示,在发送请求中可能会用到 function uuid(num) { var s = []; var hexDigits = "01234567 ...

  5. 21天学通PythonPDF高清完整版免费下载|百度云盘

    百度云盘:21天学通PythonPDF高清完整版免费下载 提取码:nqa9 豆瓣评分: 书籍封面: 内容简介  · · · · · · <21天学通Python>全面.系统.深入地讲解了P ...

  6. Jenkins部署jmx脚本

      针对jenkins+jmeter做接口自动化,jmeter完成测试脚本录入和撰写,而jenkins负责持续集成和报告收集.那么从零实现jenkins可以从以下角度实现 首先需要安装jenkins ...

  7. spring 循环依赖的一次 理解

    前言: 在看spring 循环依赖的问题中,知道原理,网上一堆的资料有讲原理. 但今天在看代码过程中,又产生了疑问. 疑问点如下: // 疑问点: 先进行 dependon 判断String[] de ...

  8. Python os.fstatvfs() 方法

    概述 os.fstatvfs() 方法用于返回包含文件描述符fd的文件的文件系统的信息,类似 statvfs().高佣联盟 www.cgewang.com Unix上可用. fstatvfs 方法返回 ...

  9. PHP array_reverse() 函数

    实例 返回翻转顺序的数组: <?php $a=array("a"=>"Volvo","b"=>"BMW" ...

  10. PHP move_uploaded_file() 函数

    定义和用法 move_uploaded_file() 函数把上传的文件移动到新位置. 如果成功该函数返回 TRUE,如果失败则返回 FALSE. 语法 move_uploaded_file(file, ...