题意:

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

思路:

      果断二分+2sat,现在我们来看下怎么建边,首先我们把每把钥匙用看成a,不用看成~a ,对于没一组钥匙,我们不能同时选择两个,所以有 x ->~y ,y -> ~x,对于门,我们每次至少选择开一个,所以有 ~x -> y ,~y -> x,就这样二分每次重新建图就行了,顺便说下POJ2723 ,跟这个题目几乎差不多,但是唯一的区别就是那个题目每组钥匙不会重复,这个有可能是同一把钥匙属于多个组,如果用这个题目的代码直接去交POJ2723,直接就可以AC了,钥匙反过来就不一定了,因为那个题目既然说是一把钥匙最多只出现在一组,那么就没有必要把每把钥匙拆成a
和 ~a ,而是把每组的钥匙拆成 a ~a,这样就节省了点数和时间,同时也没有必要建 x ->~y y->~x,这样也节省的边,如果是那么做的,那么到这个题目上就WA了,所以我说这个代码粘到那个代码上肯定AC,反过来就不一定了。


#include<stdio.h>
#include<string.h>
#include<stack> #define N_node 5000
#define N_edge 50000

using namespace
std; typedef struct
{
int
to ,next;
}
STAR; STAR E1[N_edge] ,E2[N_edge];
int
list1[N_node] ,list2[N_node] ,tot;
int
Belong[N_node] ,cnt;
int
mark[N_node];
int
D[N_node][2] ,A[N_node][2];
int
id[N_node];
stack<int>st; void add(int a ,int b)
{

E1[++tot].to = b;
E1[tot].next = list1[a];
list1[a] = tot;
a = a + b ,b = a - b ,a = a - b;
E2[tot].to = b;
E2[tot].next = list2[a];
list2[a] = tot;
} void
DFS1(int s)
{

mark[s] = 1;
for(int
k = list1[s] ;k ;k = E1[k].next)
if(!
mark[E1[k].to]) DFS1(E1[k].to);
st.push(s);
} void
DFS2(int s)
{

mark[s] = 1;
Belong[s] = cnt;
for(int
k = list2[s] ;k ;k = E2[k].next)
if(!
mark[E2[k].to]) DFS2(E2[k].to);
} bool
ok(int mid ,int n)
{

memset(list1 ,0 ,sizeof(list1));
memset(list2 ,0 ,sizeof(list2));
tot = 1;
for(int
i = 1 ; i<= n/2 ;i ++)
{
int
x = A[i][0] * 2 ,xx = A[i][0] * 2 + 1;
int
y = A[i][1] * 2 ,yy = A[i][1] * 2 + 1;
add(x ,yy) ,add(y ,xx);
} for(int
i = 1 ;i <= mid ;i ++)
{
int
x = D[i][0] * 2 ,xx = D[i][0] * 2 + 1;
int
y = D[i][1] * 2 ,yy = D[i][1] * 2 + 1;
add(xx ,y) ,add(yy ,x);
}

memset(mark ,0 ,sizeof(mark));
while(!
st.empty()) st.pop();
for(int
i = 0 ;i < n * 2 ;i ++)
if(!
mark[i]) DFS1(i);
memset(mark ,0 ,sizeof(mark));
cnt = 0;
while(!
st.empty())
{
int
xin = st.top();
st.pop();
if(
mark[xin]) continue;
cnt ++;
DFS2(xin);
}
int
mk = 0;
for(int
i = 0 ;i < n * 2 && !mk;i += 2)
if(
Belong[i] == Belong[i^1]) mk = 1;
return !
mk;
} int main ()
{
int
i ,n ,m ,a ,b;
while(~
scanf("%d %d" ,&n ,&m) && n + m)
{
for(
i = 1 ;i <= n ;i ++)
{

scanf("%d %d" ,&a ,&b);
A[i][0] = a ,A[i][1] = b;
}
for(
i = 1 ;i <= m ;i ++)
scanf("%d %d" ,&D[i][0] ,&D[i][1]);
int
low ,up , mid ,ans = 0;
low = 0 ,up = m ,n *= 2;
while(
low <= up)
{

mid = (low + up) >> 1;
if(
ok(mid ,n))
ans = mid ,low = mid + 1;
else
up = mid - 1;
}

printf("%d\n" ,ans);
}
return
0;
}

hdu1816 + POJ 2723开锁(二分+2sat)的更多相关文章

  1. poj 2723 Get Luffy Out 2-SAT

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

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

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

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

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

  4. HDU 3622 Bomb Game(二分+2SAT)

    题意:有一个游戏,有n个回合,每回合可以在指定的2个区域之一放炸弹,炸弹范围是一个圈,要求每回合的炸弹范围没有重合.得分是炸弹半径最小的值.求可以得到的最大分数. 思路:二分+2SAT. 二分炸弹范围 ...

  5. java模拟开锁

    java模拟开锁 service qq:928900200 Introduction to Computer Science II: CSCI142Fall 2014Lab #1Instructor: ...

  6. 4位开锁<dfs>

    题意: 有一个四位密码的锁,每一位是1~9的密码,1跟9相连.并且相邻的连个密码位可以交换.每改变一位耗时1s,给出锁的当前状态和密码,求最少解锁时间. 思路: 用bfs枚举出所有相邻交换的情况,并记 ...

  7. hihocoder 1075 : 开锁魔法III

    描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜将会随机地选择 k 个盒子用魔法将它 ...

  8. #1075 : 开锁魔法III

    描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜将会随机地选择 k 个盒子用魔法将它 ...

  9. Hiho #1075: 开锁魔法III

    Problem Statement 描述 一日,崔克茜来到小马镇表演魔法. 其中有一个节目是开锁咒:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它.初始时,崔克茜 ...

随机推荐

  1. Python3+pygame实现的90坦克大战 代码完整 有演示效果

    我是一个典型的80后,年轻时玩过了特别多的游戏,所以这几天用Python3+pygame实现了一个另外小游戏"坦克大战"(其他的游戏,请翻阅我的博客) 本实例代码量有些多,完整的版 ...

  2. Asp.Net Core WebAPI中启用XML格式数据支持

    因为XML是一种非常常用的数据格式,所以Asp.Net core提供了非常便利的方式来添加对XML格式的支持 只需要在IOC注册Controller服务的后面跟上.AddXmlDataContract ...

  3. Go中定时器实现原理及源码解析

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的go的源码15.7,需要注意的是由于timer是1.14版本进行改版,但是1. ...

  4. SpringBoot启动流程原理解析(二)

    在上一章我们分析了SpingBoot启动流程中实例化SpingApplication的过程. return new SpringApplication(primarySources).run(args ...

  5. 不用任何框架,Java 就能实现定时任务的 3 种方法!

    是的,不用任何框架,用我们朴素的 Java 编程语言就能实现定时任务. 今天,栈长就介绍 3 种实现方法,教你如何使用 JDK 实现定时任务! 1. sleep 这也是我们最常用的 sleep 休眠大 ...

  6. WPF 基础 - x 名称空间详解

    名称 种类(默认Attribute) 备注 x:Array 标记拓展 可作为 ListBox.ItemsSource 的值 x:Class 指定与 .cs 中哪个类合并,所指示的类型在声明时使用 pa ...

  7. jQuery学习笔记(1) 初识jQuery

    目录 目录 引用 注意 HelloWorldHelloWorld! jQueryjQuery对象和DOMDOM对象的相互转换 冲突的解决 引用 本地文件引用: <script src=" ...

  8. 王兴:为什么中国的 ToB 企业都活得这么惨?

    本文节选自美团创始人王兴的内部讲话.在讲话中,王兴罕见地分享了他对全球和中国宏观经济的理解,谈了他对 TO B 业务的深度思考. 我们今天讲一下餐饮生态业务部,以及对我们整个公司在整个业务发展过程中的 ...

  9. PReact10.5.13源码理解

    React源码看过几次,每次都没有坚持下来,索性学习一下PReact部分,网上讲解源码的不少,但是基本已经过时,所以自己来梳理下 render.js部分 import { EMPTY_OBJ, EMP ...

  10. 使用Gensim库对文本进行词袋、TF-IDF和n-gram方法向量化处理

    Gensim库简介 机器学习算法需要使用向量化后的数据进行预测,对于文本数据来说,因为算法执行的是关于矩形的数学运算,这意味着我们必须将字符串转换为向量.从数学的角度看,向量是具有大小和方向的几何对象 ...