POJ 2723 Get Luffy Out(2-SAT+二分答案)
| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 8851 | Accepted: 3441 |
Description
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?
Input
Output
Sample Input
3 6
0 3
1 2
4 5
0 1
0 2
4 1
4 2
3 5
2 2
0 0
Sample Output
4
题目链接:POJ 2723
用2-SAT来check的二分答案的一道题目,由于题目的门是从上到下顺序进入的,因此才能二分这个位置,然后检测第1道门~第mid道门是否均能通过。
那么就简单了,首先把钥匙拆成两个点,用和不用,然后一共有2N个钥匙,那么就有4N个点,然后每次建图肯定是先把钥匙的矛盾点建好,然后再用1~mid的门的信息再加入一些边,然后check方案是否存在即可,一开始想不出来怎么做后来发现是按输入的顺序来开门的,然后如果一个钥匙pair为 a与b,如果你选了a,那么b会消失,但a可以一直用,不会消失,感觉以前大一的时候也在某一个网络赛里见过这个题,意思基本相同就题面变一下,可惜当时并不懂2-SAT……写了个暴力dfs结果T了……惨
代码:
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <sstream>
#include <numeric>
#include <cstring>
#include <bitset>
#include <string>
#include <deque>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = (1 << 10) + 10;
const int MAXV = N << 2;
const int MAXE = N * 6;
struct edge
{
int to, nxt;
edge() {}
edge(int _to, int _nxt): to(_to), nxt(_nxt) {}
};
edge E[MAXE];
int head[MAXV], tot;
int vis[MAXV], st[MAXV], top;
int n, m;
int door[N << 1][2], key[N][2]; int rev(int k)
{
return k < (n << 1) ? k + (n << 1) : k - (n << 1);
}
inline void add(int s, int t)
{
E[tot] = edge(t, head[s]);
head[s] = tot++;
}
void init()
{
CLR(head, -1);
tot = 0;
CLR(vis, 0);
}
int dfs(int u)
{
if (vis[rev(u)])
return 0;
if (vis[u])
return 1;
vis[u] = 1;
st[top++] = u;
for (int i = head[u]; ~i; i = E[i].nxt)
{
int v = E[i].to;
if (!dfs(v))
return 0;
}
return 1;
}
int check()
{
for (int i = 0; i < (n << 2); ++i)
{
top = 0;
if (!vis[i] && !vis[rev(i)] && !dfs(i))
{
while (top)
vis[st[--top]] = 0;
if (!dfs(rev(i)))
return 0;
}
}
return 1;
}
void build(int last)
{
init();
for (int i = 0; i < n; ++i) //2n
{
add(key[i][0], rev(key[i][1]));
add(key[i][1], rev(key[i][0]));
}
for (int i = 1; i <= last; ++i) //2m
{
add(rev(door[i][0]), door[i][1]);
add(rev(door[i][1]), door[i][0]);
}
}
int main(void)
{
int i;
while (~scanf("%d%d", &n, &m) && (n || m))
{
init();
for (i = 0; i < n; ++i)
scanf("%d%d", &key[i][0], &key[i][1]);
for (i = 1; i <= m; ++i)
scanf("%d%d", &door[i][0], &door[i][1]);
int L = 0, R = m;
int ans = 0;
while (L <= R)
{
int mid = MID(L, R);
build(mid);
if (check())
{
ans = mid;
L = mid + 1;
}
else
R = mid - 1;
}
printf("%d\n", ans);
}
return 0;
}
POJ 2723 Get Luffy Out(2-SAT+二分答案)的更多相关文章
- HDU 1816, POJ 2723 Get Luffy Out(2-sat)
HDU 1816, POJ 2723 Get Luffy Out pid=1816" target="_blank" style="">题目链接 ...
- poj 2723 Get Luffy Out(2-sat)
Description Ratish is a young man who always dreams of being a hero. One day his friend Luffy was ca ...
- POJ 3294 Life Forms(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3294 [题目大意] 求出在至少在一半字符串中出现的最长子串. 如果有多个符合的答案,请按照字典序输出. [题解] 将所有的字符串通 ...
- POJ 3080 Blue Jeans(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3080 [题目大意] 求k个串的最长公共子串,如果存在多个则输出字典序最小,如果长度小于3则判断查找失败. [题解] 将所有字符串通 ...
- poj 2723 Get Luffy Out 二分+2-sat
题目链接 给n个钥匙对, 每个钥匙对里有两个钥匙, 并且只能选择一个. 有m扇门, 每个门上有两个锁, 只要打开其中一个就可以通往下一扇门. 问你最多可以打开多少个门. 对于每个钥匙对, 如果选择了其 ...
- poj 2723 Get Luffy Out-2-sat问题
Description Ratish is a young man who always dreams of being a hero. One day his friend Luffy was ca ...
- TTTTTTTTTTTTTTTT POJ 2723 楼层里救朋友 2-SAT+二分
Get Luffy Out Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 8211 Accepted: 3162 Des ...
- poj 2723 Get Luffy Out 2-SAT
两个钥匙a,b是一对,隐含矛盾a->!b.b->!a 一个门上的两个钥匙a,b,隐含矛盾!a->b,!b->a(看数据不大,我是直接枚举水的,要打开当前门,没选a的话就一定要选 ...
- POJ 2758 Checking the Text(Hash+二分答案)
[题目链接] http://poj.org/problem?id=2758 [题目大意] 给出一个字符串,支持两个操作,在任意位置插入一个字符串,或者查询两个位置往后的最长公共前缀,注意查询的时候是原 ...
随机推荐
- java之接口相关知识
1.接口用interface来声明 //定义一个动物接口 public interface Animal{ public void eat(); public void travel(); } 2.接 ...
- python_7_while
count=0 while True: print('count:',count) count+=1 # count=count+1 if count==500: break#结束整个循环
- python换行
python中如果一行代码太长,看着不方便时,怎么办? 只需要在需要换行的地方添加上符号 \ 就行了.
- Everything Be True-freecodecamp算法题目
Everything Be True 1.要求 完善every函数,如果集合(collection)中的所有对象都存在对应的属性(pre),并且属性(pre)对应的值为真.函数返回ture.反之,返回 ...
- 螺旋矩阵,两步进阶,从暴力到o(1)
题目描述 一个 n 行 n 列的螺旋矩阵可由如下方法生成: 从矩阵的左上角(第 1 行第 1 列)出发,初始时向右移动:如果前方是未曾经过的格子,则继续前进,否则右转:重复上述操作直至经过矩阵中所有格 ...
- 两种方法实现text输入框中“请输入关键字”的提醒
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- python 写 组合两两组合
紧挨着 组合 a b c d ----> ab ,bc ,cd portList = ['a', 'b', 'c', 'd'] for i, p in enumerate(portList) ...
- python 输入英语单词,查看汉语意思
# -*- coding:utf-8 -*- import urllib2 import lxml.html as HTML def get_wordmean(): url = 'http://www ...
- eclipse projectExplorer视图(以包的方式显示)与navigator视图切换(以文件夹的方式显示)及树状视图与平面视图的切换
projectExplorer与navigator的切换 projectExplorer视图效果 想要此视图效果步骤如下: 分割------------------------------------ ...
- django处理上传文件配置
1.sttings中配置 'django.template.context_processors.media' TEMPLATES = [ { 'BACKEND': 'django.template. ...