POJ2723 题解
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 题解的更多相关文章
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...
- noip2016十连测题解
以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...
- BZOJ-2561-最小生成树 题解(最小割)
2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ...
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ...
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...
- 2016ACM青岛区域赛题解
A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ...
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...
- 网络流n题 题解
学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...
- CF100965C题解..
求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...
随机推荐
- gin中从reader读取数据数据
package main import ( "fmt" "github.com/gin-gonic/gin" "net/http" &quo ...
- fluentd学习笔记
转载自http://blog.csdn.net/qq_27252133/article/details/53520416 原文https://blog.laisky.com/p/fluentd/ 最近 ...
- 学习Java第15天
今天所做的工作: 学习了HTML的基本标签,vs code的基本使用 明天工作安排: 继续学习html 目前所遇到的大都是HTML标签数量多,较复杂的问题,继续找规律记忆吧.
- python 小兵(9)生成器
生成器 首先我们来看看什么是个生成器,生成器本质就是迭代器 在python中有三种方式来获取生成器 1.通过生成器函数 2.通过各种推到式来实现生成器 3.通过数据的转换也可以获取生成器 首先,我们先 ...
- hashmap 实现 相同的key值时,value值叠加效果。
一,了解一些基础 package com.ohs.demo; /** * * 一.需求是:停止相同的key值,覆盖效果,将重复的value值,叠加起来. * * 二.hash? 什么是hash? * ...
- th 表达式的简单使用。
一.使用场景,页面中,循环遍历,获得控制器穿过来的值. 1.1 控制器 /** * 获得所有的图书信息 * @return */ @RequestMapping("/turnIndexPag ...
- 实际工程中加快 Java 代码编写的小提示
这里我简单谈谈 Java 语法在编程效率方面的弱势,以及如何补救. 一.集合的快速创建 C# 是少数拥有集合字面值(又叫初始化表达式)的静态语言之一. var list = new List<i ...
- Redis 常见面试题(2020最新版)
阶段汇总集合:001期~180期汇总,方便阅读(增加设计模式) 概述 什么是Redis Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许可) ...
- java getSource()和 getActionCommand()区别
感谢大佬:https://blog.csdn.net/LIU_YANZHAO/article/details/72740011?utm_source=blogxgwz1 比如说 按纽的事件,同一个JF ...
- Jmeter测试dubbo接口填坑
通过jmeter测试dubbo的方法网上有很多帖子,需要的自己度娘去就可以. 使用的时候有个问题需要提示一下,因为我碰到了,还耽误了一些时间,不说中间的过程.直接说处理方式: 问题是这样的: 将dub ...