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 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?

Input

There are several test cases. Every test case starts with a line containing two positive integers N (1 <= N <= 210) and M (1 <= M <= 211) separated by a space, the first integer represents the number of types of keys and the second integer represents the number of doors. The 2N keys are numbered 0, 1, 2, ..., 2N - 1. Each of the following N lines contains two different integers, which are the numbers of two keys in a pair. After that, each of the following M lines contains two integers, which are the numbers of two keys corresponding to the two locks in a door. You should note that the doors are given in the same order that Ratish will meet. A test case with N = M = 0 ends the input, and should not be processed.

Output

For each test case, output one line containing an integer, which is the maximum number of doors Ratish can open.

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

今天学习了 2-sat问题  这是一个现实中经常遇到的问题可以转化为图论去解决

有m扇门,每扇门都有两把锁,只要打开其中一把就可以打开这扇门,

打开了第i扇门才能继续开第i+1扇门。

现在有2n个钥匙,每两个绑在一起,使用了一个就不能使用另一个。

问最多能开几扇门。

这个就是 2-sat问题的模板题

  以下是这类问题的基本的解题思路

  1. 构造有向图,这个有向图是一个表示了选择了一个点,一定要选择它能够到达的点的图。
  2. 对这个图求强连通图。
  3. 假如有两个点处在同一个强连通图内,这两个点是必须只能选择一个的一组内的点,就不可以。
  4. 否则可以

  a->b+2*n 表示 选a不选b

  门的建边就要 a+2*n->b

  然后判断 a和a+2*n 在不在同一个强连通分量内

  回到题目来 这题的话网上普遍二分解决 因为这样快啊

  

  

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 #include <string>
 6 #include <algorithm>
 7 #include <queue>
 8 #include <stack>
 9
10 using namespace std;
11 const int maxn = 1e5 + 10;
12 const int  mod = 1e9 + 7 ;
13 const int INF = 0x7ffffff;
14 struct node {
15     int v, next;
16 } edge[maxn];
17 int head[maxn], dfn[maxn], low[maxn];
18 int s[maxn], belong[maxn], instack[maxn];
19 int tot, cnt, top, flag, n, m;
20 void init() {
21     tot = cnt = top = flag = 0;
22     memset(s, 0, sizeof(s));
23     memset(head, -1, sizeof(head));
24     memset(dfn, 0, sizeof(dfn));
25     memset(instack, 0, sizeof(instack));
26 }
27 void add(int u, int v ) {
28     edge[tot].v = v;
29     edge[tot].next = head[u];
30     head[u] = tot++;
31 }
32 void tarjin(int v) {
33     dfn[v] = low[v] = ++flag;
34     instack[v] = 1;
35     s[top++] = v;
36     for (int i = head[v] ; ~i ; i = edge[i].next ) {
37         int j = edge[i].v;
38         if (!dfn[j]) {
39             tarjin(j);
40             low[v] = min(low[v], low[j]);
41         } else if (instack[j]) low[v] = min(low[v], dfn[j]);
42     }
43     if (dfn[v] == low[v]) {
44         cnt++;
45         int t;
46         do {
47             t = s[--top];
48             instack[t] = 0;
49             belong[t] = cnt;
50         } while(t != v) ;
51     }
52 }
53 struct p {
54     int u, v;
55 } qu[maxn];
56 int check(int mid) {
57     init();
58     for (int i = 0 ; i < n ; i++) {
59         add(qu[i].v, qu[i].u + 2 * n);
60         add(qu[i].u, qu[i].v + 2 * n);
61     }
62     for (int i = 0 ; i < mid ; i++ ) {
63         add(qu[i + n].u + 2 * n, qu[i+n].v);
64         add(qu[i + n].v + 2 * n, qu[i+n].u);
65     }
66     for (int i = 0 ; i < 4 * n ; i++)
67         if (!dfn[i]) tarjin(i);
68     for (int i = 0 ; i < 2 * n ; i++)
69         if (belong[i] == belong[i + 2 * n]) return 0;
70     return 1;
71 }
72 int main() {
73     while(scanf("%d%d", &n, &m) != EOF) {
74         if (n == 0 && m == 0  ) break;
75         for (int i = 0 ; i < n ; i++)
76             scanf("%d%d", &qu[i].u, &qu[i].v);
77         for (int i = 0 ; i < m ; i++)
78             scanf("%d%d", &qu[i + n].u, &qu[i + n].v);
79         int low = 0, high = m, mid;
80         while(low <= high) {
81             mid = (low + high) / 2;
82             if (check(mid)) low = mid + 1;
83             else high = mid - 1;
84         }
85         printf("%d\n", high);
86     }
87     return 0;
88 }

原文地址:https://www.cnblogs.com/qldabiaoge/p/9092918.html

时间: 2024-10-10 08:23:38

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="">题目链接 题意:N串钥匙.每串2把,仅仅能选一把.然后有n个大门,每一个门有两个锁,开了一个就能通过,问选一些钥匙,最多能通过多少个门 思路:二分通过个数.然后对于钥匙建边至少一个不选,门建边至少一个选,然后2-sat搞一下就可以. 一開始是按每串钥匙为1个结点,但是后面发现数据有可能一把钥匙,出如今不同串(真是不合

POJ 2723 Get Luffy Out(图论-2SAT,搜索-二分)

Get Luffy Out Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7488   Accepted: 2845 Description 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 Arlo

poj 2723 Get Luffy Out 2-sat

题意: 有2*n把钥匙配成n对,每对中只能使用一把,另外有m道门,每道门能被2把药匙打开,问最多能从1开始按顺序打开多少道门. 分析: 二分枚举能打开的门数,用2-sat算法判断能否打开. 代码: //poj 2723 //sep9 #include <iostream> #include <cstdio> #include <string.h> #include <stack> using namespace std; const int maxN=100

POJ 2723 Get Luffy Out(2-SAT)

[题目链接] http://poj.org/problem?id=2723 [题目大意] 给出一些钥匙和M扇有顺序的门,每扇门可以用两种钥匙打开, 每两把钥匙被绑在一起,绑在一起的钥匙只有其中一把可以使用, 问最多能按顺序打开几扇门. [题解] 因为门是按顺序的,因此能打开的门是单调, 首先我们二分这个答案,判定是否可行, 将二分得到的答案之前的门按两个钥匙孔拆分成两个点, 两个绑在一起的钥匙属于对立面,而门的两个钥匙孔是OR关系 A与B之间的OR关系,我们可以将其拆分为!A->B AND !B

poj 2723

Get Luffy Out Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7295   Accepted: 2778 Description 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 Arlo

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

Language: Default Get Luffy Out Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7969   Accepted: 3061 Description Ratish is a young man who always dreams of being a hero. One day his friend Luffy was caught by Pirate Arlong. Ratish set o

(2 sat) poj 2723

Get Luffy Out Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7758   Accepted: 2969 Description 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 Arlo

【图论补完计划】poj 2723(2-SAT)

Get Luffy Out Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 8688   Accepted: 3371 Description 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 Arlo

图论常用算法之一 POJ图论题集【转载】

POJ图论分类[转] 一个很不错的图论分类,非常感谢原版的作者!!!在这里分享给大家,爱好图论的ACMer不寂寞了... (很抱歉没有找到此题集整理的原创作者,感谢知情的朋友给个原创链接) POJ:http://poj.org/ 1062* 昂贵的聘礼 枚举等级限制+dijkstra 1087* A Plug for UNIX 2分匹配 1094 Sorting It All Out floyd 或 拓扑 1112* Team Them Up! 2分图染色+DP 1125 Stockbroker