典型的2-sat问题,题意:有m个门,每个门上俩把锁,开启其中一把即可,现在给n对钥匙(所有

钥匙编号0123456...2n-1),每对钥匙只能用一把,要求尽可能开门多(按顺序,前max个)。

关键是题意的分析与转化,只能选一?必然2-sat,每给一对门上的锁对应钥匙的编号,说:必需要这

俩把钥匙的一把(至少),即:a^b,所以,建图了可以,总结通法:对应的数据编号:0123..,每个

数代表原来的一个“状态”/“命题”/“数据”,使之01为一对(只取一个),23一对,...依次,建图

此题要求最值,二分即可。

注意点(WA之因):1.编号后全图全按编号走啊!原来数据基本无用,只是有时候输出时之用,或建立

数据双向关系!2.对于每次二分,对应数要重新建图,注意初始化!

ps:一晚没成功,结果早上起来2分钟,AC!上午效率就是高!切记不可熬夜!身体健康第一位!

#include<iostream>    //36MS
#include<cstring>
#include<cstdio>
#include<stack>
#include<vector>
using namespace std;
const int MAX=3000;
vector<int>keys(MAX);int n,m;int times=0;
int belong[MAX];
int low[MAX];int dfn[MAX];int visited[MAX];int isinstack[MAX];stack<int>s;
int scc[MAX];int numblock=0;
struct request //条件
{
int a,b;
};
request requests[MAX];
vector<vector<int> >edges(MAX); //图
void clear()
{
times=numblock=0;
for(int i=0;i<2*n;i++)
{
visited[i]=dfn[i]=low[i]=isinstack[i];
scc[i]=-1;
edges[i].clear();
}
}
void tarjan(int u) //dfs
{
dfn[u]=low[u]=++times;
isinstack[u]=1;
s.push(u); int len=edges[u].size();
for(int i=0;i<len;i++)
{
int v=edges[u][i];
if(visited[v]==0)
{
visited[v]=1;
tarjan(v);
if(low[u]>low[v])low[u]=low[v];
}
else if(isinstack[v]&&dfn[v]<low[u])
low[u]=dfn[v];
}
if(low[u]==dfn[u])
{
numblock++;int cur;
do
{
cur=s.top();s.pop();
isinstack[cur]=0;
scc[cur]=numblock;
}while(cur!=u);
}
}
bool check(int maxnum) //检查
{
clear();
for(int i=0;i<maxnum;i++) //这里的数据的转化
{
if(requests[i].a==requests[i].b)
{
edges[belong[requests[i].a]^1].push_back(belong[requests[i].b]);
}
else
{
edges[belong[requests[i].a]^1].push_back(belong[requests[i].b]);
edges[belong[requests[i].b]^1].push_back(belong[requests[i].a]);
}
}
for(int i=0;i<2*n;i++)
if(visited[i]==0)
{
visited[i]=1;
tarjan(i);
}
for(int i=0;i<2*n;i+=2)
if(scc[i]==scc[i+1]) //因为这里跪了半天!注意编号!图顶点用的都是编号!
return 0;
return 1;
}
void readin()
{
for(int i=0;i<2*n;i++)
{
scanf("%d",&keys[i]);
belong[keys[i]]=i;
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&requests[i].a,&requests[i].b);
}
}
int main()
{
while(~scanf("%d%d",&n,&m)&&(n||m))
{
readin();
int left=0,right=m,mid;
int count=-1;
while(right>left) //二分之
{
mid=(left+right)/2;
if(mid==count&&mid==left) //注意出口!
{
if(check(left+1))left++;
break;
}
if(check(mid))
left=mid;
else right=mid;
count=mid;
}
printf("%d\n",left);
}
}

poj2723 2sat判断解+二分的更多相关文章

  1. BZOJ 2199: [Usaco2011 Jan]奶牛议会 [2-SAT 判断解]

    http://www.lydsy.com/JudgeOnline/problem.php?id=2199 题意:裸的2-SAT,但是问每个变量在所有解中是只能为真还是只能为假还是既可以为真又可以为假 ...

  2. hdu3715 Go Deeper[二分+2-SAT]/poj2723 Get Luffy Out[二分+2-SAT]

    这题转化一下题意就是给一堆形如$a_i + a_j \ne c\quad (a_i\in [0,1],c\in [0,2])$的限制,问从开头开始最多到哪条限制全是有解的. 那么,首先有可二分性,所以 ...

  3. hdu 3622(二分+2-sat判断可行性)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3622 思路:二分是容易想到的,由于题目中有明显的矛盾关系,因此可以用2-sat来验证其可行性.关键是如 ...

  4. 【判断解是否可行-二分】POJ1064-Cable master

    http://poj.org/problem?id=1064 [题目大意] 给出几条绳子的长度,问如果要切出k条长度相等的绳子,这k条绳子最常多长? [思路] 二分.把下界设为0,上界设为所有绳子长度 ...

  5. hdu3622 2-sat问题,二分+判断有无解即可。

    /*2-sat问题初破!题意:每一对炸弹只能选一个(明显2-sat),每个炸弹半径自定,爆炸范围不可 相交,求那个最小半径的最大值(每种策略的最小半径不同).思:最优解:必然是选择的点最近 的俩个距离 ...

  6. POJ 3683 Priest John's Busiest Day[2-SAT 构造解]

    题意: $n$对$couple$举行仪式,有两个时间段可以选择,问是否可以不冲突举行完,并求方案 两个时间段选择对应一真一假,对于有时间段冲突冲突的两人按照$2-SAT$的规则连边(把不冲突的时间段连 ...

  7. Uva LA 3177 - Beijing Guards 贪心,特例分析,判断器+二分,记录区间内状态数目来染色 难度: 3

    题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

  8. The Accomodation of Students HDU - 2444(判断二分图 + 二分匹配)

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  9. hdu 2444 The Accomodation of Students 判断二分图+二分匹配

    The Accomodation of Students Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

随机推荐

  1. 后TOS时代的码头数字化生产力

    之前看过一篇文章是,是INFORM的副总裁写的关于以TOS外挂模式提升码头生产效能的文章.文章对外挂模式的总结挺好的,我最近也一直从事这块的工作,以此文梳理一下前面的经验,记录一下自己的感想. TOS ...

  2. VC++编译出错:LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

    解决方法: 1.搜索C盘下的cvtres.exe,结果得到类似这样的列表: C:\Program Files\Microsoft Visual Studio 10.0\VC\bin C:\Window ...

  3. 基于 python 的接口测试框架

    项目背景 公司内部的软件采用B/S架构,管理实验室数据,实现数据的存储和分析统计.大部分是数据的增删改查,由于还在开发阶段,所以UI界面的变化非常快,之前尝试过用python+selenium进行UI ...

  4. easyui权限管理

    在easyui上实现权限的管理 所谓权限:指的是系统中的资源,资源包括菜单资源(学习情况报表,账号审核...)以及按钮资源所谓角色:指的是系统中的权限集合(每一个角色对应着哪些权限集合) 1.一星权限 ...

  5. PRJ0003 : Error spawning 'midl.exe'

    原因:出现该错误的是由于:C:\Program Files\Microsoft SDKs\Windows\v6.0A midl.exe 和midlc.exe缺失. 解决方法:从别人电脑上拷贝这个两个文 ...

  6. PHP02 PHPStrom2018.X与WAMPServer3.0.6的集成

    脚本运行环境设置:设置PHPStorm中的脚本在PHP解析器上运行 1.进入Filie>>>setting>>languages and FrameWorks 选择php ...

  7. cf上分的失落->高兴->更失落

    cf昨日做出一个题居然div2打了1800多名直接上分了...我原以为垂直落地但是....我现在1399差一分就能蓝名了啊啊啊啊,以后不一定会有这个水平的啊,给个蓝名体验卡不行吗,多加一分会死啊... ...

  8. 关于C/C++的一些思考(5)

    运算符重载函数的限制: 五个不能实现重载的符号:".", ".*", "::", "?", "sizeof&q ...

  9. Mybatis 头信息

    在使用IDEA开发中,如果不使用Mybatis-Generator时,那么就需要手写Mapper文件,而在创建xml文件时无法直接创建带有mybatis头信息的mapper文件,这里来记录一下Myba ...

  10. 提高CPU使用率

    某些特殊时候,需要提升下cpu的利用率,此时……………………需要一个极其简单的脚本来完成! #!/bin/bash while (true);do { for i in $(seq 100000 10 ...