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 在不在同一个强连通分量内

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

  

  

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
#include <stack> using namespace std;
const int maxn = 1e5 + ;
const int mod = 1e9 + ;
const int INF = 0x7ffffff;
struct node {
int v, next;
} edge[maxn];
int head[maxn], dfn[maxn], low[maxn];
int s[maxn], belong[maxn], instack[maxn];
int tot, cnt, top, flag, n, m;
void init() {
tot = cnt = top = flag = ;
memset(s, , sizeof(s));
memset(head, -, sizeof(head));
memset(dfn, , sizeof(dfn));
memset(instack, , sizeof(instack));
}
void add(int u, int v ) {
edge[tot].v = v;
edge[tot].next = head[u];
head[u] = tot++;
}
void tarjin(int v) {
dfn[v] = low[v] = ++flag;
instack[v] = ;
s[top++] = v;
for (int i = head[v] ; ~i ; i = edge[i].next ) {
int j = edge[i].v;
if (!dfn[j]) {
tarjin(j);
low[v] = min(low[v], low[j]);
} else if (instack[j]) low[v] = min(low[v], dfn[j]);
}
if (dfn[v] == low[v]) {
cnt++;
int t;
do {
t = s[--top];
instack[t] = ;
belong[t] = cnt;
} while(t != v) ;
}
}
struct p {
int u, v;
} qu[maxn];
int check(int mid) {
init();
for (int i = ; i < n ; i++) {
add(qu[i].v, qu[i].u + * n);
add(qu[i].u, qu[i].v + * n);
}
for (int i = ; i < mid ; i++ ) {
add(qu[i + n].u + * n, qu[i+n].v);
add(qu[i + n].v + * n, qu[i+n].u);
}
for (int i = ; i < * n ; i++)
if (!dfn[i]) tarjin(i);
for (int i = ; i < * n ; i++)
if (belong[i] == belong[i + * n]) return ;
return ;
}
int main() {
while(scanf("%d%d", &n, &m) != EOF) {
if (n == && m == ) break;
for (int i = ; i < n ; i++)
scanf("%d%d", &qu[i].u, &qu[i].v);
for (int i = ; i < m ; i++)
scanf("%d%d", &qu[i + n].u, &qu[i + n].v);
int low = , high = m, mid;
while(low <= high) {
mid = (low + high) / ;
if (check(mid)) low = mid + ;
else high = mid - ;
}
printf("%d\n", high);
}
return ;
}

poj 2723 Get Luffy Out-2-sat问题的更多相关文章

  1. HDU 1816, POJ 2723 Get Luffy Out(2-sat)

    HDU 1816, POJ 2723 Get Luffy Out pid=1816" target="_blank" style="">题目链接 ...

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

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

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

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

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

  5. poj 2723 Get Luffy Out 2-SAT

    两个钥匙a,b是一对,隐含矛盾a->!b.b->!a 一个门上的两个钥匙a,b,隐含矛盾!a->b,!b->a(看数据不大,我是直接枚举水的,要打开当前门,没选a的话就一定要选 ...

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

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

  7. POJ 2723 HDU 1816 Get Luffy Out

    二分答案 + 2-SAT验证 #include<cstdio> #include<cstring> #include<cmath> #include<stac ...

  8. poj 2723

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

  9. POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang

    Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...

随机推荐

  1. zabbix proxy安装配置

    1.下载软件zabbix-2.2.1.tar.gz 1.1解压 tar xvf zabbix-2.2.1.tar.gz 1.2编译安装 cd zabbix-2.2.1./configure --pre ...

  2. give me something new 无用但有趣

    屏保系列 http://www.asty.org/cmatrix/dist/cmatrix-1.2a.tar.gz  //数码雨 libaa-bin //燃烧 海洋馆 http://search.cp ...

  3. springMVC入门二

    一.准备工作 参考springMVC入门一,搭建maven项目如下: 前台结构如下: 项目介绍:使用springMVC实现前后台数据交互,例如controller返回json,页面传入pojo 二.具 ...

  4. Oracle 11g R2在 win7 64位的安装流程图解【含常见问题解决方案】

    ORACLE数据库系统是美国ORACLE公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(CLIENT/SERVER)或B/S体系结构的数据库之一.Oracle 11 ...

  5. 实用jquery插件

    jquery toast 一个弹窗插件 jquery.form.min.js 一个Ajax表单插件

  6. Python必学:使用哪款文本编辑器更好?

    Python的交互式命令行写程序,好处是一下就能得到结果,坏处是没法保存,下次还想运行的时候,还得再敲一遍. 所以,实际开发的时候,我们总是使用一个文本编辑器来写代码,写完了,保存为一个文件,这样,程 ...

  7. C语言字符篇(一)字符串转换函数

      #include <stdlib.h>   double atof(const char *nptr);  将字符串转换成双精度浮点数 int atoi(const char *npt ...

  8. 树上dfs+思维

    #include<cstdio> ; int cnt,head[N],n; int size[N],num[N]; void init() { cnt = ; ;i<N;i++) h ...

  9. pdfmake实现中文支持,解决中文乱码问题

    引言:当初自己为了在项目中bootstrap-table中实现导出pdf,使用的pdfmake,但是pdfmake默认使用的不是中文字体,实现pdfmake使用中文字体主要就是编译新的vfs_font ...

  10. 怎么设置才能让外网ip可以访问mysql数据库[转]

    转自: http://www.hongyanliren.com/89.html 使用mysql中,很多人都会遇到这样的问题:在vps服务器或者云服务器上安装了mysql后,使用其他工具在外网ip之下根 ...