HDU 1816 Get Luffy Out *(2-SAT+二分)
来源:互联网 发布:流体力学分析软件 编辑:程序博客网 时间:2024/05/23 20:37
题目地址
题意:给你n串钥匙,每串钥匙有2把不同编号的钥匙,有一栋m层楼高的房子,每层有2个门,告诉你每个门要的钥匙,可能不同的门有相同的扼钥匙,但是一把钥匙打开了一个门,开完以后就会消失,问你最多能上几层。
思路:一看就是两判性的问题,两判性的问题解决方法就是2-SAT(说了不知道多少遍了),建图就老老实实建,判断一下他的限制关系:把每个钥匙拆成两个点(一个为选这把钥匙,一个为不选),然后二选一的话就把一串钥匙中的一把选与另一把的不选连边,然后开门的话就是开第一个门就不用开第二个门了,然后对应的钥匙选与不选连边就好了。
#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 6010#define M 1000010//双倍#define LL __int64#define inf 0x3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 1000000007;const double eps = 0.001;int n, m;int head[N], idx;struct node { int to; int next;}edge[M];struct cows { int x, y;}key[N], lock[N];struct two_SAT { int dfn[N], low[N]; int stack[N], top; int belong[N], cnt, num; bool vis[N]; void init() { memset(head, -1, sizeof(head)); memset(belong, 0, sizeof(belong)); memset(dfn, 0, sizeof(dfn)); memset(vis, false, sizeof(vis)); num = cnt = 0; top = 0; idx = 0; } void addedge(int a, int b) { edge[idx].to = b; edge[idx].next = head[a]; head[a] = idx++; } void tarjin(int u) {//缩点 dfn[u] = low[u] = ++num; vis[u] = true; stack[top++] = u; for (int i = head[u]; ~i; i = edge[i].next) { int v = edge[i].to; if (!dfn[v]) { tarjin(v); low[u] = min(low[u], low[v]); } else if (vis[v]) { low[u] = min(low[u], dfn[v]); } } if (dfn[u] == low[u]) { while (true) { int v = stack[--top]; vis[v] = false; belong[v] = cnt;//标记联通分量belong if (u == v) break; } cnt++; } } bool two_sat() { for (int i = 0; i < 4 * n; i++) {//总点数 if (!dfn[i]) tarjin(i); } for (int i = 0; i < 4 * n; i += 2) {//遍历是不是会有一个人有2种可能 if (belong[i] == belong[i + 1]) { return false; } } return true; }}sat;bool check(int num) { sat.init(); for (int i = 0; i < n; i++) {//key*2为取这把钥匙 key*2+1为不取这把钥匙 int x = key[i].x * 2; int y = key[i].y * 2 + 1; sat.addedge(x, y); sat.addedge(y ^ 1, x ^ 1); } for (int i = 0; i < num; i++) {//开第一个门就不用开第二个门了 int x = lock[i].x * 2 + 1; int y = lock[i].y * 2; sat.addedge(x, y); sat.addedge(y ^ 1, x ^ 1); } return sat.two_sat();}int main() { cin.sync_with_stdio(false); while (cin >> n >> m) { if (n == 0 && m == 0) { break; } for (int i = 0; i < n; i++) { cin >> key[i].x >> key[i].y; } for (int i = 0; i < m; i++) { cin >> lock[i].x >> lock[i].y; } int l = 0, r = m; int ans = -1; while (l <= r) { int mid = (l + r) / 2; if (check(mid)) { ans = mid; l = mid + 1; } else r = mid - 1; } cout << ans << endl; } return 0;}
阅读全文
0 0
- HDU 1816 Get Luffy Out *(2-SAT+二分)
- HDU - 1816 Get Luffy Out *(二分 + 2-SAT)
- Get Luffy Out * (2-sat + 二分)
- HDU 1816 Get Luffy Out *(2-SAT)
- POJ 2723 && HDU 1816 Get Luffy Out(2-SAT+二分)
- poj2723 Get Luffy Out (二分+2-SAT)
- hdu1816 Get Luffy Out *--二分 & 2-sat
- poj2723 Get Luffy Out (二分+2-SAT)
- poj 2723 Get Luffy Out(2-sat + 二分)
- Get Luffy Out (poj 2723 二分+2-SAT)
- 【HDU】1816 Get Luffy Out * &【POJ】2723 Get Luffy Out 【2-sat】
- HDU 1816, POJ 2723 Get Luffy Out(2-sat)
- 【2-sat】 HDOJ 1816 Get Luffy Out *
- 2-SAT(Tarjan)—— Get Luffy Out *(HDU 1816)
- [2-sat+二分]poj 2723 Get Luffy Out
- POJ 2723 Get Luffy Out(2-SAT + 二分)
- POJ 2723 Get Luffy Out 二分 2-SAT
- Poj 2723 Get Luffy Out (2-SAT + 二分)
- 敌兵布阵(简单线段树)
- JavaScript深入学习[1]
- vue-cli 路由嵌套
- 第一篇:对jni和NDK的认识
- java
- HDU 1816 Get Luffy Out *(2-SAT+二分)
- 862A. Mahmoud and Ehab and the MEX
- POJ3273 Monthly Expense 二分法
- 人工智能入门简介及行业分析
- SAS数据集如何将为负数的部分,变为正数
- HDU 5127 Dogs' Candies【CDQ分治+动态凸包】
- 分析Hibernate:could not initialize proxy
- PHP的异步、并行、高性能网络通信引擎swoole的安装及websocket服务的使用
- [转]配置sonar、jenkins进行持续审查