今天看到讲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思想);

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cstring>
  5. #include <string>
  6. #include <vector>
  7. #include <map>
  8. #include <set>
  9. #include <queue>
  10. #include <stack>
  11. #include <list>
  12. #include <iterator>
  13.  
  14. using namespace std;
  15.  
  16. #define pb push_back
  17.  
  18. const int maxn = +;
  19. int n,m;
  20. int key[maxn][],locks[maxn][];
  21. int low[maxn],dfn[maxn],vis[maxn],belong[maxn],scc,tot;
  22. stack<int>s;
  23. vector<int>mp[maxn];
  24.  
  25. void tarjan(int x)
  26. {
  27. dfn[x] = low[x] = ++tot;
  28. s.push(x);vis[x] = ;
  29. for(int i=; i<mp[x].size(); i++)
  30. {
  31. int v = mp[x][i];
  32. if(dfn[v]==)
  33. {
  34. tarjan(v);
  35. low[x] = min(low[x],low[v]);
  36. }
  37. else if(vis[v])
  38. {
  39. low[x] = min(low[x],dfn[v]);
  40. }
  41. }
  42. if(low[x]==dfn[x])
  43. {
  44. scc++;
  45. while()
  46. {
  47. int tmp = s.top();
  48. s.pop();
  49. vis[tmp] = ;
  50. belong[tmp] = scc;
  51. if(tmp==x)break;
  52. }
  53. }
  54. }
  55. void init()
  56. {
  57. for(int i=; i<=*n; i++)mp[i].clear();
  58. }
  59. void build(int x)
  60. {
  61. init();
  62. for(int i=; i<=n; i++) //因为mp不得不清空.所以连这个也要重新建
  63. {
  64. int a = key[i][],b = key[i][];
  65. mp[a].pb(b+*n);
  66. mp[b].pb(a+*n);
  67. }
  68. for(int i=; i<=x; i++)
  69. {
  70. int a = locks[i][],b = locks[i][];
  71.  
  72. mp[a+*n].pb(b); //对于开门来说,不用这把,就要用另一把钥匙;
  73. if(a!=b)mp[b+*n].pb(a);
  74. }
  75. }
  76.  
  77. void ini(){
  78. while(!s.empty())s.pop();
  79. scc = tot = ;
  80. memset(low,,sizeof(low));
  81. memset(dfn,,sizeof(dfn));
  82. memset(vis,,sizeof(vis));
  83. memset(belong,,sizeof(belong));
  84. }
  85. bool check(){
  86. ini();
  87. for(int i=; i<=*n; i++)
  88. {
  89. if(dfn[i]==)tarjan(i);
  90. }
  91. for(int i=; i<=*n; i++)
  92. if(belong[i]==belong[i+*n])
  93. return false;
  94. return true;
  95. }
  96. int main(){
  97. while(~scanf("%d%d", &n, &m)&&n+m)
  98. {
  99. for(int i=; i<=n; i++)
  100. {
  101. scanf("%d%d",&key[i][],&key[i][]);
  102. key[i][]++,key[i][]++;
  103. }
  104. for(int i=; i<=m; i++)
  105. {
  106. scanf("%d%d", &locks[i][], &locks[i][]);
  107. locks[i][]++,locks[i][]++;
  108. }
  109.  
  110. int le = ,ri = m; //二分范围不要乱写!
  111. int ans;
  112. while(le<=ri)
  113. {
  114. int mid = (le + ri)>>;
  115. build(mid);
  116. if(check())
  117. {
  118. ans = mid;
  119. le = mid + ;
  120. }
  121. else ri = mid - ;
  122. }
  123. printf("%d\n",ans);
  124. }
  125. return ;
  126. }

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. Linux下安装配置Jmeter5.1,并执行jmx文件

    Windows下的jmeter是GUI模式,可查看操作,但是GUI对性能的干扰比较大,所有一般压测会在Linux上运行. 下面是Linux下安装配置Jmeter5.1,并执行jmx文件的步骤, 一.安 ...

  2. 一文了解:Redis事务

    Redis事务 事务提供了一种"将多个命令打包,一次性提交并按顺序执行"的机制,提交后在事务执行中不会中断.只有在执行完所有命令后才会继续执行来自其他客户的消息. Redis中的使 ...

  3. 记一次paramiko远程连接遇到的坑

    背景:工作中遇到了一个问题,需要用到windows向windows连接(文件传发)以及,linux向windows连接(文件传发)的需求. 自然而然会考虑到用paramiko,然而paramiko我用 ...

  4. 一次简单的SQL手工注入

    1. 首先要了解SQL注入的原理:   SQL Injection:就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令. 具体来说,它是利 ...

  5. 把Jar包加入windows系统服务

    之前在服务器上不一个Java服务时候,总是开着一堆黑框框,非常不雅,重点是极其容易误关,所以把可执行Jar文件加入Windows系统服务,看起来是个非常不错的选择!(实际上也确实是非常不错的选择) ! ...

  6. 在vue-cli 3中, 给stylus、sass样式传入共享的全局变量

    在开发中有时,我们定义了大量的基础样式变量,例如: 大量的vue单文件组件会用到这些变量,每个组件都引人一次又太麻烦.全局引入是个不错的方法,于是,在main.js 中引入variable.styl文 ...

  7. 想转行大数据,开始学习 Hadoop?

    学习大数据首先要了解大数据的学习路线,首先搞清楚先学什么,再学什么,大的学习框架知道了,剩下的就是一步一个脚印踏踏实实从最基础的开始学起. 这里给大家普及一下学习路线:hadoop生态圈——Strom ...

  8. todaytt

    <?xml version="1.0" encoding="utf-8"?> <android.support.v4.widget.Drawe ...

  9. 史上最全面的SignalR系列教程-3、SignalR 实现推送功能-集线器类实现方式

    1.概述 通过前两篇 史上最全面的SignalR系列教程-1.认识SignalR 史上最全面的SignalR系列教程-2.SignalR 实现推送功能-永久连接类实现方式 文章对SignalR的介绍, ...

  10. 爬虫之爬取电影天堂(request)

    #需要通过代码打开https://www.dytt8.net/网站,拿到网站内容 from urllib.request import urlopen #拿到urlopen import re con ...