Get Luffy Out *

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 978    Accepted Submission(s): 426

Problem 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 made N pairs,one key may be appear in some 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 <= 2^10) and M (1 <= M <= 2^11) 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 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

Hint

题目有更改!

 

Source

 
二分能够到达的层数。
首先每队钥匙之间建边。
然后前deep层的锁建边。
2-SAT判定是否可行。
  1. //2017-08-28
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <iostream>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <cmath>
  8.  
  9. using namespace std;
  10.  
  11. const int N = ;
  12. const int M = N*N*;
  13. int head[N], rhead[N], tot, rtot;
  14. struct Edge{
  15. int to, next;
  16. }edge[M], redge[M];
  17.  
  18. void init(){
  19. tot = ;
  20. rtot = ;
  21. memset(head, -, sizeof(head));
  22. memset(rhead, -, sizeof(rhead));
  23. }
  24.  
  25. void add_edge(int u, int v){
  26. edge[tot].to = v;
  27. edge[tot].next = head[u];
  28. head[u] = tot++;
  29.  
  30. redge[rtot].to = u;
  31. redge[rtot].next = rhead[v];
  32. rhead[v] = rtot++;
  33. }
  34.  
  35. vector<int> vs;//后序遍历顺序的顶点列表
  36. bool vis[N];
  37. int cmp[N];//所属强连通分量的拓扑序
  38.  
  39. //input: u 顶点
  40. //output: vs 后序遍历顺序的顶点列表
  41. void dfs(int u){
  42. vis[u] = true;
  43. for(int i = head[u]; i != -; i = edge[i].next){
  44. int v = edge[i].to;
  45. if(!vis[v])
  46. dfs(v);
  47. }
  48. vs.push_back(u);
  49. }
  50.  
  51. //input: u 顶点编号; k 拓扑序号
  52. //output: cmp[] 强连通分量拓扑序
  53. void rdfs(int u, int k){
  54. vis[u] = true;
  55. cmp[u] = k;
  56. for(int i = rhead[u]; i != -; i = redge[i].next){
  57. int v = redge[i].to;
  58. if(!vis[v])
  59. rdfs(v, k);
  60. }
  61. }
  62.  
  63. //Strongly Connected Component 强连通分量
  64. //input: n 顶点个数
  65. //output: k 强连通分量数;
  66. int scc(int n){
  67. memset(vis, , sizeof(vis));
  68. vs.clear();
  69. for(int u = ; u < n; u++)
  70. if(!vis[u])
  71. dfs(u);
  72. int k = ;
  73. memset(vis, , sizeof(vis));
  74. for(int i = vs.size()-; i >= ; i--)
  75. if(!vis[vs[i]])
  76. rdfs(vs[i], k++);
  77. return k;
  78. }
  79.  
  80. int n, m;
  81. pair<int, int> key[N], lock[N];
  82.  
  83. //二分层数
  84. bool check(int deep){
  85. init();
  86. for(int i = ; i < n; i++){
  87. //add_edge(key[i].first, key[i].second+2*n);
  88. add_edge(key[i].second+*n, key[i].first);// NOT v -> u
  89. //add_edge(key[i].second, key[i].first+2*n);
  90. add_edge(key[i].first+*n, key[i].second);// NOT u -> v
  91. }
  92. for(int i = ; i < deep; i++){
  93. add_edge(lock[i].first, lock[i].second+*n);// u -> NOT v
  94. //add_edge(lock[i].second+2*n, lock[i].first);
  95. add_edge(lock[i].second, lock[i].first+*n);// v -> NOT u
  96. //add_edge(lock[i].first+2*n, lock[i].second);
  97. }
  98. scc(*n);
  99. for(int i = ; i < *n; i++){
  100. if(cmp[i] == cmp[i+*n])
  101. return false;
  102. }
  103. return true;
  104. }
  105.  
  106. int main()
  107. {
  108. std::ios::sync_with_stdio(false);
  109. //freopen("inputF.txt", "r", stdin);
  110. while(cin>>n>>m){
  111. if(!n && !m)break;
  112. for(int i = ; i < n; i++)
  113. cin>>key[i].first>>key[i].second;
  114. for(int i = ; i < m; i++)
  115. cin>>lock[i].first>>lock[i].second;
  116. int l = , r = m, mid, ans = ;
  117. while(l <= r){
  118. mid = (l+r)/;
  119. if(check(mid)){
  120. ans = mid;
  121. l = mid+;
  122. }else
  123. r = mid-;
  124. }
  125. cout<<ans<<endl;
  126. }
  127. return ;
  128. }

HDU1816(二分+2-SAT)的更多相关文章

  1. hdu1816 + POJ 2723开锁(二分+2sat)

    题意:      有m层门,我们在最外层,我们要一层一层的进,每一层上有两把锁,我们只要开启其中的一把们就会开,我们有n组钥匙,每组两把,我们只能用其中的一把,用完后第二把瞬间就会消失,问你最多能开到 ...

  2. 证明与计算(3): 二分决策图(Binary Decision Diagram, BDD)

    0x01 布尔代数(Boolean algebra) 大名鼎鼎鼎的stephen wolfram在2015年的时候写了一篇介绍George Boole的文章:George Boole: A 200-Y ...

  3. Map Labeler POJ - 2296(2 - sat 具体关系建边)

    题意: 给出n个点  让求这n个点所能建成的正方形的最大边长,要求不覆盖,且这n个点在正方形上或下边的中点位置 解析: 当然是二分,但建图就有点还行..比较难想..行吧...我太垃圾... 2 - s ...

  4. LA 3211 飞机调度(2—SAT)

    https://vjudge.net/problem/UVALive-3211 题意: 有n架飞机需要着陆,每架飞机都可以选择“早着陆”和“晚着陆”两种方式之一,且必须选择一种,第i架飞机的早着陆时间 ...

  5. UVALive - 3211 (2-SAT + 二分)

    layout: post title: 训练指南 UVALive - 3211 (2-SAT + 二分) author: "luowentaoaa" catalog: true m ...

  6. hdu3715 2-sat+二分

    Go Deeper 题意:确定一个0/1数组(size:n)使得满足最多的条件数.条件在数组a,b,c给出. 吐槽:哎,一水提,还搞了很久!关键是抽象出题目模型(如上的一句话).以后做二sat:有哪些 ...

  7. POJ 2749 2SAT判定+二分

    题意:图上n个点,使每个点都与俩个中转点的其中一个相连(二选一,典型2-sat),并使任意两点最大 距离最小(最大最小,2分答案),有些点相互hata,不能选同一个中转点,有些点相互LOVE,必需选相 ...

  8. 2 - sat 模板(自用)

    2-sat一个变量两种状态符合条件的状态建边找强连通,两两成立1 - n 为第一状态(n + 1) - (n + n) 为第二状态 例题模板 链接一  POJ 3207 Ikki's Story IV ...

  9. BZOJ1012: [JSOI2008]最大数maxnumber [线段树 | 单调栈+二分]

    1012: [JSOI2008]最大数maxnumber Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 8748  Solved: 3835[Submi ...

随机推荐

  1. 代码审计| HDWiki 漏洞(一)

    i春秋核心白帽:yanzm 0×00 背景 最近拿到一个源码素材于是对这个源码进行分析发现了不少漏洞本篇先将一些漏洞进行分析下一篇再进行GetShell方法的分析期待和师傅们的交流. 0×01 漏洞分 ...

  2. java urlrewrite实现伪静态化

    1.示例 http://www.onlyfun.com/goods/company.jsp?companyId=455326 ==> http://www.onlyfun.com/company ...

  3. 套接字:Socket

    在进行通信之前,一般要先建立Socket连接,Socket编程是端到端的通信,往往意识不到中间经过了多少局域网,多少路由器,他能操作的是端到端协议之上的网络层和传输层. 在网络层,Socket函数可以 ...

  4. day 71 crm(8) 权限组件的设置,以及权限组件的应用

    ---恢复内容开始--- 前情提要: strak 组件是增删改查组件 , 生活中,需求权限组件,  不足: 1,前后端不分离,   2, 空url也会刷新界面,造成资源浪费   3,如果角色忘记设置权 ...

  5. Liferay开发实战(1):入门

    网址: https://www.liferay.com/zh/ 文档: https://dev.liferay.com/develop 入门文章网上很多,中文的较少,存在版本太旧的问题,也缺少一步一步 ...

  6. redis缓存存在的隐患及其解决方案

    redis缓存1.缓存穿透 1>.什么是缓存穿透? 业务系统需要查训的数据根本不存在,当业务系统查询时, 首先会在缓存中查训,由于缓存中不存在,然后在往数据 库中查,由于该数据在数据库中也不存在 ...

  7. JS 跨域认识及如何解决

    什么是跨域 指的是浏览器不允许javascrip脚本向其他域名发起ajax请求. 跨域的各种情况判定 URL 说明 是否允许通信 http://www.a.com/a.js http://www.a. ...

  8. Mysql数据引擎和系统库

    系统数据库 information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息.列信息.权限信息.字符信息等performance_schema: MySQL ...

  9. 使用Jenkins部署.Net应用程序

    首先从 https://jenkins.io/download/ 下载所需的版本 这里选择Windows版本来测试. 直接安装jenkins.msi,安装完后使用Win+R输入services.msc ...

  10. Java中带包(创建及引用)的类的编译

    Java中带包(创建及引用)的类的编译与调试 java源程序的编译大家都知道,也就是cmd中到源文件所在目录下javac **.java即可,当程序中有包声明还能简简单单的直接javac **.jav ...