WA了半天才发现居然是因为没看见这道题有多组数据,wzfl。。。

题目大意:有N对钥匙,对于每一对钥匙,如果使用了其中一把,另一把钥匙就会消失。接下来有M扇门,每扇门上有两把锁,分别对应两把钥匙(锁会重复出现,每把钥匙也可以重复使用),打开其中任意一把就可以打开这扇门,再打开第m扇门后才可以去尝试打开第m+1扇门。问最多能打开多少扇门。

思路:每个钥匙都有使用与不使用两种状态且必须是其中一种状态,于是想到2-SAT,对于配对的钥匙a,b,使用了一个之后另一个就不能使用 ,所以在图中连边(a,¬b)和(b,¬a)。

对于每个门上的两个钥匙c,d,如果门能打开,就一定有一个钥匙被使用,所以如果不用其中一个,就必须用另外一个,所以在图中连边(¬c,d)和(¬d,c)。

由于必须从第一扇们门开始向后连续尝试开门,接下来通过二分就能找到可以打开的最大门数,对于每个门数e,处理前e个门的钥匙,如果该2-SAT有解,就说明可以打开e扇门,否则不行。

代码如下:

//POJ.2723
//Author: Prgl
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) typedef long long ll;
typedef vector<int>vec; #define INF 0x3f3f3f3f
const int maxv = 1 << 14;
const int maxd = 1 << 15; int V;
vec G[maxv], rG[maxv];
stack<int>s;
bool used[maxv];
int cmp[maxv]; inline void add_edge(int from, int to)
{
G[from].push_back(to);
rG[to].push_back(from);
} void dfs(int v)
{
used[v] = true;
for (int i = 0; i < G[v].size(); i++)
{
if (!used[G[v][i]])
dfs(G[v][i]);
}
s.push(v);
} void rdfs(int v, int k)
{
cmp[v] = k;
used[v] = true;
for (int i = 0; i < rG[v].size(); i++)
{
if (!used[rG[v][i]])
rdfs(rG[v][i], k);
}
} int scc()
{
memset(used, 0, sizeof(used));
for (int v = 0; v < V; v++)
{
if (!used[v])
dfs(v);
}
memset(used, 0, sizeof(used));
int k = 0;
while (!s.empty())
{
int v = s.top();
s.pop();
if (!used[v])
rdfs(v, k++); } return k;
} int N, M, K;
int a[maxv], b[maxv];
int A[maxd], B[maxd]; bool C(int d)
{
for (int v = 0; v < V; v++)
{
G[v].clear();
rG[v].clear();
}
for (int i = 0; i < N; i++)
{
add_edge(a[i], b[i] + K);
add_edge(b[i], a[i] + K);
}
for (int i = 0; i < d; i++)
{
add_edge(B[i] + K, A[i]);
add_edge(A[i] + K, B[i]);
}
memset(cmp, 0, sizeof(cmp));
scc();
for (int i = 0; i < K; i++)
{
if (cmp[i] == cmp[i + K])
return false;
} return true;
} void solve()
{
K = N * 2;
V = N * 4;
int lo = 0, hi = M + 1;
while (hi - lo > 1)
{
int mi = (lo + hi) / 2;
if (C(mi))
lo = mi;
else
hi = mi;
}
cout << lo << endl;
} int main()
{
IOS;
cin >> N >> M;
while (N != 0 || M != 0)
{
for (int i = 0; i < N; i++)
cin >> a[i] >> b[i];
for (int i = 0; i < M; i++)
cin >> A[i] >> B[i];
solve();
cin >> N >> M;
} return 0;
}

POJ2723 题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. Go 循环控制

    #### Go 循环控制昨天有工作要忙, 断更一天,不过学习的事情,还是每天要坚持; 我还有头发, 还能学习^_^.***倘若我心中的山水, 你眼中都看到***上一节学习完流程控制,总结一下switc ...

  2. Docker+etcd+flanneld+kubernets 构建容器编排系统(1)

    Docker: Docker Engine, 一个client-server 结构的应用, 包含Docker daemon,一个 用来和daemon 交互的REST API, 一个命令行应用CLI. ...

  3. Filter的拦截路径

    Filter的拦截路径 精确匹配 <url-pattern>/target.jsp</url-pattern> 以上配置的路径,表示请求地址必须为:http://ip.port ...

  4. javaObject—toString方法

    1 package face_object; 2 /* 3 * Object:所有类的根类. 4 * Object是不断抽取而来的,具备所有对象都具备的共性内容. 5 * 常用的共性功能: 6 * 7 ...

  5. pycharm 安装插件

    1.使用pip安装插件 pip安装指定版本的插件: pip install openpyxl==2.6.2 -i https://pypi.doubanio.com/simple/ -i后面跟的是&q ...

  6. Linux 配置 SVN and ideal 配置SVN的客户端 ?

    Linux 配置 SVN? 4.配置svn(服务器端) 项目管理工具(subversion),每个公司都会用到(git/svn) 目的就是为了合作开发 4.1.从linux上安装svn 不需要从官网下 ...

  7. 如何在 pyqt 中解决国际化 tr() 函数不起作用的问题

    前言 有些时候我们在父类中使用了 self.tr('XXX'),使用 Qt Linguist 完成翻译并导出 qm 文件后,发现子类中仍然是英文原文.比如下面这段代码: class AlbumCard ...

  8. Activity的生命周期 (必须掌握)

      onCreate 方法 当Activity第一次启动的时候调用   onDestroy 方法 当Activity销毁的时候调用   onStart() 方法 当Activity变成可见的时候调用  ...

  9. vi/vim 设置.vimrc(/etc/vim | $HOME)

    转载请注明来源:https://www.cnblogs.com/hookjc/ "====================================================== ...

  10. Net6 DI源码分析Part4 CallSiteFactory ServiceCallSite

    Net6 CallSiteFactory ServiceCallSite, CallSiteChain abstract class ServiceCallSite ServiceCallSite是个 ...