今天看到讲2-SAT比较好的blog,感觉微微的理解了2-SAT

传送门

参考: https://blog.csdn.net/leolin_/article/details/6680144

题意:你有2*n把钥匙,但是在每一对钥匙中,用了a,就不能用b。你要用这么多钥匙去开尽可能多的门。开门的规则是:每个门对于两把钥匙,用一把去开就ok。

注意2的10次方一点都不大~~1000。

思路:注意开门是有顺序的,所以可以二分答案,每次用mid值规定的门数去建一个图,跑一边tarjan缩点,再check一下i和i+2*n,若是同一个缩点块中,则false(2-sat思想);

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <list>
#include <iterator> using namespace std; #define pb push_back const int maxn = +;
int n,m;
int key[maxn][],locks[maxn][];
int low[maxn],dfn[maxn],vis[maxn],belong[maxn],scc,tot;
stack<int>s;
vector<int>mp[maxn]; void tarjan(int x)
{
dfn[x] = low[x] = ++tot;
s.push(x);vis[x] = ;
for(int i=; i<mp[x].size(); i++)
{
int v = mp[x][i];
if(dfn[v]==)
{
tarjan(v);
low[x] = min(low[x],low[v]);
}
else if(vis[v])
{
low[x] = min(low[x],dfn[v]);
}
}
if(low[x]==dfn[x])
{
scc++;
while()
{
int tmp = s.top();
s.pop();
vis[tmp] = ;
belong[tmp] = scc;
if(tmp==x)break;
}
}
}
void init()
{
for(int i=; i<=*n; i++)mp[i].clear();
}
void build(int x)
{
init();
for(int i=; i<=n; i++) //因为mp不得不清空.所以连这个也要重新建
{
int a = key[i][],b = key[i][];
mp[a].pb(b+*n);
mp[b].pb(a+*n);
}
for(int i=; i<=x; i++)
{
int a = locks[i][],b = locks[i][]; mp[a+*n].pb(b); //对于开门来说,不用这把,就要用另一把钥匙;
if(a!=b)mp[b+*n].pb(a);
}
} void ini(){
while(!s.empty())s.pop();
scc = tot = ;
memset(low,,sizeof(low));
memset(dfn,,sizeof(dfn));
memset(vis,,sizeof(vis));
memset(belong,,sizeof(belong));
}
bool check(){
ini();
for(int i=; i<=*n; i++)
{
if(dfn[i]==)tarjan(i);
}
for(int i=; i<=*n; i++)
if(belong[i]==belong[i+*n])
return false;
return true;
}
int main(){
while(~scanf("%d%d", &n, &m)&&n+m)
{
for(int i=; i<=n; i++)
{
scanf("%d%d",&key[i][],&key[i][]);
key[i][]++,key[i][]++;
}
for(int i=; i<=m; i++)
{
scanf("%d%d", &locks[i][], &locks[i][]);
locks[i][]++,locks[i][]++;
} int le = ,ri = m; //二分范围不要乱写!
int ans;
while(le<=ri)
{
int mid = (le + ri)>>;
build(mid);
if(check())
{
ans = mid;
le = mid + ;
}
else ri = mid - ;
}
printf("%d\n",ans);
}
return ;
}

POJ2723 Get Luffy Out解题报告tarjan+2-SAT+二分的更多相关文章

  1. hrbustoj 1494(原题UVA 315 Network) 解题报告 tarjan求割点

    主要思路:使用tarjan选取一个根节点建立一个棵搜索树,判断一个点是割点的充分必要条件是,对于一个节点u如果他的孩子节点v的low值大于等于u的出生日期dfn值,进行下一步判断,如果u是我们选的根节 ...

  2. Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)

     http://blog.csdn.net/geniusluzh/article/details/6619575 在说Tarjan算法解决桥和边双连通分量问题之前我们先来回顾一下Tarjan算法是如何 ...

  3. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  4. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  5. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  6. 【NOIP2015】提高组D1 解题报告

    P1978神奇的幻方 Accepted 描述 幻方是一种很神奇的 N ∗ N 矩阵:它由数字 1,2,3, … … , N ∗ N 构成,且每行.每列及两条对角线上的数字之和都相同. 当 N 为奇数时 ...

  7. 冲刺Noip2017模拟赛5 解题报告——五十岚芒果酱

    1. 公约数(gcd) [问题描述] 给定一个正整数,在[,n]的范围内,求出有多少个无序数对(a,b)满足 gcd(a,b)=a xor b. [输入格式] 输入共一行,一个正整数n. [输出格式] ...

  8. Codeforces Educational Round 92 赛后解题报告(A-G)

    Codeforces Educational Round 92 赛后解题报告 惨 huayucaiji 惨 A. LCM Problem 赛前:A题嘛,总归简单的咯 赛后:A题这种**题居然想了20m ...

  9. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

随机推荐

  1. python多进程详解

    目录 python多进程 序.multiprocessing 一.Process process介绍 例1.1:创建函数并将其作为单个进程 例1.2:创建函数并将其作为多个进程 例1.3:将进程定义为 ...

  2. UE4中UMG与C++交互 页面文本修改

    在UE4中,有两种方式创建ui,一种是使用slate的方式,一种是UMG,UMG是slate的封装,是一个可视化的ui编辑器.slate则是纯c++方式(之前实验过一次slate创建页面,代码相当麻烦 ...

  3. 客户端埋点实时OLAP指标计算方案

    背景 产品经理想要实时查询一些指标数据,在新版本的APP上线之后,我们APP的一些质量指标,比如课堂连接掉线率,课堂内崩溃率,APP崩溃率等指标,以此来看APP升级之后上课的体验是否有所提升,上课质量 ...

  4. 【Java例题】2.4求函数

    4.输入x,编程试求函数 y=sin(x^2)/(1-cosx)的值. 这里的"^"表示乘方. package study; import java.util.Scanner; p ...

  5. Unity通过NTP获取网络时间

    最初通过qq时间服务器获得时间,经常出现有网络也获取失败的情况. 后面寻找解决办法,查找资料终于发现通过ntp时间服务器获取网络时间的方法.   首先游戏开始获得初始化网络时间,通常只获取一次,其他时 ...

  6. Java——数据结构(顺序表)

    这是一个顺序表的类,初始化的时候就已经确定了表的长度,之后不能添加数据,因为使用的是数组存储的数据,不过这个表的类型是泛型的. public class List { private Object[] ...

  7. Servlet生成验证码并进行账号密码和验证码的验证登陆!

    前言: 人不是生来就懂事的,在编程的世界也是一样,想想在大一的时候我还是那个连输出Hello World!都不会的小孩子是,现在我已经可以编出属于我自己的小程序了.编程其实并不可怕,可怕的是你不去编. ...

  8. Oracle - SPM固定执行计划(一)

    一.前言 生产中偶尔会碰到一些sql,有多种执行计划,其中部分情况是统计信息过旧造成的,重新收集下统计信息就行了.但是有些时候重新收集统计信息也解决不了问题,而开发又在嗷嗷叫,没时间让你去慢慢分析原因 ...

  9. LD_PRELOAD和ld --wrap

    前言 LD_PRELOAD和ld --wrap都能实现不修改原始代码,替换指定函数的实现.通常我们会使用这些方法,替换如malloc)()/free().read()/write()等函数,并在替换函 ...

  10. 解决Springboot整合ActiveMQ发送和接收topic消息的问题

    环境搭建 1.创建maven项目(jar) 2.pom.xml添加依赖 <parent> <groupId>org.springframework.boot</group ...