LOJ2723
LOJ2723 Get Luffy Out
题目大意:给你n对钥匙,每对钥匙只可以用其中的任意一个,钥匙有编号,且不重复。有m个大门,每个门上有两个锁,每个锁对应一个编号的钥匙,只要打开两个锁中的一个就可以打开门。问用这n对钥匙最多可以打开多少大门(门有顺序)?
——————————————————————————————————————————————
每一个大门要打开,要么用A钥匙,要么用B钥匙,这是明现的2-SAT问题。
同一对钥匙,用了A钥匙就一定不能用B钥匙。
对于最多可以打开多少门,因为门有顺序,所以要二分答案。
——————————————————————————————————————————————
1 #include<cstdio>
2 #include<iostream>
3 #include<algorithm>
4 #include<cstring>
5 using namespace std;
6 const int maxn=1050;
7 const int maxm=2100;
8 int n,m;
9 int keys[maxn<<1],doors[maxm][2];
10 struct edge
11 {
12 int u,v,nxt;
13 }e[maxm<<1];
14 int head[maxn<<1],js;
15 void addage(int u,int v)
16 {
17 e[++js].u=u;e[js].v=v;
18 e[js].nxt=head[u];head[u]=js;
19 }
20 int low[maxm<<1],dfn[maxm<<1],cnt,st[maxm<<1],top,lt[maxm<<1],lts;
21 void tarjan(int u)
22 {
23 low[u]=dfn[u]=++cnt;
24 st[++top]=u;
25 for(int i=head[u];i;i=e[i].nxt)
26 {
27 int v=e[i].v;
28 if(!dfn[v])
29 {
30 tarjan(v);
31 low[u]=min(low[u],low[v]);
32 }
33 else if(!lt[v]) low[u]=min(low[u],dfn[v]);
34 }
35 if(low[u]==dfn[u])
36 {
37 lt[u]=++lts;
38 while(st[top]!=u)lt[st[top--]]=lts;
39 --top;
40 }
41 }
42 bool pd(int x)
43 {
44 memset(head,0,sizeof head);
45 js=0;
46 for(int a,b,i=0;i<x;++i)
47 {
48 a=doors[i][0],b=doors[i][1];
49 if(a==b)addage(keys[a]^1,keys[a]);
50 else
51 {
52 addage(keys[a]^1,keys[b]);
53 addage(keys[b]^1,keys[a]);
54 }
55 }
56 memset(low,0,sizeof low);
57 memset(dfn,0,sizeof dfn);
58 cnt=0;
59 memset(lt,0,sizeof lt);
60 lts=0;
61 top=0;
62 for(int i=2;i<n*2+2;++i)
63 if(!dfn[i])tarjan(i);
64 for(int i=1;i<n+1;++i)
65 if(lt[i<<1]==lt[(i<<1)^1])return 0;
66 return 1;
67 }
68 int main()
69 {
70 while(scanf("%d%d",&n,&m),n+m)
71 {
72 for(int a,b,i=1;i<=n;++i)
73 {
74 scanf("%d%d",&a,&b);
75 keys[a]=i<<1;
76 keys[b]=(i<<1)^1;
77 }
78 for(int i=0;i<m;++i)
79 scanf("%d%d",&doors[i][0],&doors[i][1]);
80 int l=0,r=m,ans=0;
81 while(l<=r)
82 {
83 int mid=(l+r)>>1;
84 if(pd(mid))ans=mid,l=mid+1;
85 else r=mid-1;
86 }
87 printf("%d\n",ans);
88 }
89 return 0;
90 }
LOJ2723的更多相关文章
随机推荐
- VNC使用及其常见问题解决方法
博主之前在博文(https://www.cnblogs.com/kangbazi666/p/14153604.html)中已经介绍了多人VNC的配置方法,下面将简单介绍其使用方法及常见问题的解决方法. ...
- Lightweight Render Pipeline
(翻译) Lightweight Render Pipeline (LWRP),轻量级渲染管线,是一个Unity预制的Scriptable Render Pipeline (SRP).LWRP可以为移 ...
- TCP实现网络通讯
Tcp server的流程:1.创建套接字:2.bind绑定ip和port3.listen使套接字变为可以被动链接:4.accept等待客户端的链接(返回为服务器分配的客户端的句柄和地址)5.reci ...
- vue中携带token以及发送ajax
在项目中基本登录都会存在token,而我们也就需要在每次发送ajax的时候就必须携带他.从而最有效的办法,就是在设置请求头携带token,这样设置一次后面的每一次都会携带着这个token. 一:设置请 ...
- linux脚本错误: line *: [: missing `]',linux编写shell脚本时的注意点
转载:https://www.cnblogs.com/bovenson/p/4548079.html 关于shell的一些注意点,粘贴自拉钩教育精选评论:测试开发核心技术 46 讲-->第6讲 ...
- 想学Python不知如何入门,教你!
一.入门引导 想必有很多小伙伴想学习Python,又不知道如何入门,总觉得学习一定要头悬梁,锥刺股!NO,今天给大家分享下如何轻松入门Python! 首先,我们要学习Python,那一定要和你 ...
- 【Flutter】布局类组件之对齐和相对定位
前言 如果只想简单的调整一个子元素在父元素中的位置的话,使用Align组件会更简单一些. 接口描述 const Align({ Key key, // 需要一个AlignmentGeometry类型的 ...
- LeetCode222 判断是否为完全二叉树并求节点个数
给出一个完全二叉树,求出该树的节点个数. 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置.若最底 ...
- Docker学习笔记之Dockerfile
Dockerfile的编写格式为<命令><形式参数>,命令不区分大小写,但一般使用大写字母.Docker会依据Dockerfile文件中编写的命令顺序依次执行命令.Docker ...
- Python基础语法4-运算符
Python提供了一系列丰富的运算符,包括: Ø算术运算符 Ø赋值运算符 Ø关系运算符 Ø逻辑运算符 Ø位运算符 Ø三元运算符 Ø身份运算符 Ø成员运算符