POJ-2723(2-SAT)
来源:互联网 发布:网络借钱平台 编辑:程序博客网 时间:2024/05/17 22:03
题目:http://poj.org/problem?id=2723
第5道2-SAT,一开始没想起来怎么构造,然后想到了用mark[2i]表示是否开gate[i]的左边一把锁lock[2i],用mark[2i+1]表示是否开gate[i]的右边一把锁lock[2i+1],则如果lock[x]和lock[y]需要的钥匙不同且lock[x]和lock[y]需要的钥匙在同一串上(一串钥匙有两个),则构成条件开lock[x]或者开lock[y],注意到开锁要求必须从gate[0]到gate[i-1]都开完了才能开gate[i]上的锁,因此我们可以通过二分搜索满足要求的最大开门数量,毕竟如果能开N扇门,则一定能开N-1扇门。
#include <cstdio>#include <cstring>#include <vector>using namespace std;const int MAX_N = 1 << 10;const int MAX_M = 1 << 11;int N, keyPair[MAX_N * 2];int M, lockKey[MAX_M * 2];bool mark[MAX_M * 2];//for gate i, mark[2i] = true => open lock 2i; mark[2i+1] = true => open lock 2i+1vector<int> out[MAX_M * 2];int stack[MAX_M * 2], cnt;void init(int m){memset(mark, 0, 2*m);for(int i = 2*m-1; i > -1; --i) out[i].clear();}void build(int m){int i, j, a, b;for(i = 0; i < m; ++i){//2i是gate i的第一把锁a = lockKey[2 * i];for(j = i-1; j > -1; --j){//2j是gate j的第一把锁b = lockKey[2 * j];if(b != a && keyPair[b] == keyPair[a]){//lock 2i和lock 2j不能同时开//要是开2i就不能开2j,反之亦然out[2 * i].push_back(2 * j + 1);out[2 * j].push_back(2 * i + 1);}//2j+1是gate j的第二把锁b = lockKey[2 * j + 1];if(b != a && keyPair[b] == keyPair[a]){//lock 2i和lock 2j+1不能同时开//要是开2i就不能开2j+1,反之亦然out[2 * i].push_back(2 * j);out[2 * j + 1].push_back(2 * i + 1);}}//2i+1是gate i的第二把锁a = lockKey[2 * i + 1];for(j = i-1; j > -1; --j){//2j是gate j的第一把锁b = lockKey[2 * j];if(b != a && keyPair[b] == keyPair[a]){//lock 2i+1和lock 2j不能同时开//要是开2i+1就不能开2j,反之亦然out[2 * i + 1].push_back(2 * j + 1);out[2 * j].push_back(2 * i);}//2j+1是gate j的第二把锁b = lockKey[2 * j + 1];if(b != a && keyPair[b] == keyPair[a]){//lock 2i+1和lock 2j+1不能同时开//要是开2i+1就不能开2j+1,反之亦然out[2 * i + 1].push_back(2 * j);out[2 * j + 1].push_back(2 * i);}}}}bool dfs(int x){if(mark[x ^ 1]) return false;if(mark[x]) return true;mark[x] = true;stack[cnt++] = x;vector<int>& v = out[x];for(int i = v.size() - 1; i > -1; --i){if(!dfs(v[i])) return false;}return true;}bool test(int m){init(m);build(m);for(int i = 0; i < m; ++i){cnt = 0;if(!dfs(i << 1)){while(cnt) mark[stack[--cnt]] = false;if(!dfs(i << 1 | 1)) return false;}}return true;}int main(){int i, k, l, m, r;while(scanf("%d%d", &N, &M), N){//inputfor(i = 0; i < N; ++i){scanf("%d%d", &l, &r);keyPair[l] = keyPair[r] = i;}k = 0;for(i = 0; i < M; ++i){scanf("%d%d", lockKey + k, lockKey + k + 1);k += 2;}//binary searchl = 1; r = M + 1;while(l + 1 < r){m = (l + r) >> 1;if(test(m)) l = m;else r = m;}printf("%d\n", l);}return 0;}
0 0
- POJ-2723(2-SAT)
- poj 2723 2-sat
- poj 2723 2-sat
- poj 2723 2-SAT
- poj 2723 2-SAT
- poj 2723【2-SAT+二分】
- Poj 2723(two-sat)
- Poj 1703(2sat)
- POJ-3207(2-SAT)
- POJ-3678(2-SAT)
- POJ-3683(2-SAT)
- POJ-3648(2-SAT)
- poj-3678(2-SAT)
- poj 3207(2-SAT)
- POJ 2723 Get Luffy Out (2-sat)
- poj 2723 Get Luffy Out(2-sat + 二分)
- hdu1816 + POJ 2723开锁(二分+2sat)
- poj 2723 Get Luffy Out(图论-2-sat)
- 浅谈安全事件响应
- Coursera台大机器学习基础课程学习笔记1 -- 机器学习定义及PLA算法
- self.navigationItem 与 self.navigationController.navigationItem 的区别
- 【文档摘要】J2EE Persistence - Introduction to the Java Persistence API【Querying Entities】
- Python 第一章 基础知识(7) 模块
- POJ-2723(2-SAT)
- 关于聚类算法BIRCH
- [LeetCode] Add Two Numbers
- windows下arp命令
- linux shell
- 如何解决每次打开office2010都会出现正在配置
- How To Validate ASM Diskgroup Consistency/State After ASM Reclamation Utility (ASRU) Execution Abort
- sgu139:Help Needed!
- C++学习:指针