今天看到讲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. httpclient信任所有证书解决SSLException:Unrecognized SSL message,plaintext connection

    在使用 HttpClient 工具调用第三方 Http 接口时报错 javax.net.ssl.SSLException:Unrecognized SSL message,plaintext conn ...

  2. 【iOS】Assertion failure in -[MASViewConstraint install]

    刚遇到了这个问题,详细信息如下: Assertion failure 错误原因: 控件没有添加到视图就使用 mas_makeConstraints 了……应该先把控件添加到视图.

  3. netty使用EmbeddedChannel对channel的出入站进行单元测试

    一种特殊的Channel实现----EmbeddedChannel,它是Netty专门为改进针对ChannelHandler的单元测试而提供的. 名称 职责 writeInbound 将入站消息写到E ...

  4. java流压缩图片

    整理文档,搜刮出一个Java做图片压缩的代码,稍微整理精简一下做下分享.首先,要压缩的图片格式不能说动态图片,你可以使用bmp.png.gif等,至于压缩质量,可以通过BufferedImage来指定 ...

  5. 代码生成java连接数据库的所需代码(超详细)

    开始学习: round 1:(一开始学习当然还是要一步一步学习的啦,哪有什么一步登天!!!) a.准备工作:1.eclipse,mysql(这两个软件肯定要的啦,不然学什么把它们连接起来) 2.加载驱 ...

  6. JSON在线格式化 jsoneditor使用

    const placeholder = { string: 'hello world!', boolean: true, color: '#6c928c', number: 123, null: nu ...

  7. MySQL操作命令梳理(2)

    一.表操作 在mysql运维操作中会经常使用到alter这个修改表的命令,alter tables允许修改一个现有表的结构,比如增加或删除列.创造或消去索引.改变现有列的类型.或重新命名列或表本身,也 ...

  8. 【算法】【查找】二分法 Bisection

    #include<stdio.h> int main(){ ,,,,,,,,,,,,,,}; ; //长度 ; //要查找到的值 int Bisection(int x,int* a,in ...

  9. 【Java笔记】【Java核心技术卷1】chapter3 D3数据类型

    package chapter3; public class D3数据类型 { public static void main(String[] arg) { //Java 整型(字节数不会随硬件变化 ...

  10. jQuery中的append中含有onClick的问题

    在jQuery中,当append中含有onClick时,点击事件无效果.需要在append完之后再额外绑定点击事件.