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])$的限制,问从开头开始最多到哪条限制全是有解的。
那么,首先有可二分性,所以直接二分枚举最大处,然后把这些限制加边做一次2-sat就好了。连边的话注意一下细节就行,$c=0$时候就是选$0$必须另一个选$1$,$c=1$是选同类,$c=2$就是选$1$另一个必须选$0$,然后注意一下$i=j$也就是对同一变量的特殊讨论,就是直接赋值型的连边。然后就没了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=+,M=+;
struct stothx{int x,y,c;}Q[M];
int n,m,T;
struct thxorz{
int head[N],to[M<<],nxt[M<<],dfn[N],low[N],tim,stk[N],instk[N],bel[N],Top,scc,tot;
inline void clear(){mst(head),mst(dfn),tot=tim=scc=;}
inline void link(int x,int y){to[++tot]=y,nxt[tot]=head[x],head[x]=tot;}
void tarjan(int x){//dbg(x);
#define y to[j]
dfn[x]=low[x]=++tim,stk[++Top]=x,instk[x]=;
for(register int j=head[x];j;j=nxt[j]){
if(!dfn[y])tarjan(y),MIN(low[x],low[y]);
else if(instk[y])MIN(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
int tmp;++scc;
do instk[tmp=stk[Top--]]=,bel[tmp]=scc;while(tmp^x);
}
#undef y
}
inline bool check(){
for(register int i=;i<=n;++i)if(bel[i]==bel[i+n])return ;
return ;
}
}G;
inline bool check(int mid){//dbg(mid);
G.clear();
for(register int i=;i<=mid;++i){
int x=Q[i].x,y=Q[i].y,c=Q[i].c;
if(x==y){
if(c==)G.link(x,x+n);
else if(c==)G.link(x+n,x);
}
else{
if(c==)G.link(x,y+n),G.link(y,x+n);
else if(c==)G.link(x,y),G.link(y,x),G.link(x+n,y+n),G.link(y+n,x+n);
else G.link(x+n,y),G.link(y+n,x);
}
}
for(register int i=;i<=n<<;++i)if(!G.dfn[i])G.tarjan(i);
return G.check();
} int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
read(T);while(T--){
read(n),read(m);
for(register int i=;i<=m;++i)read(Q[i].x),read(Q[i].y),read(Q[i].c),++Q[i].x,++Q[i].y;
int L=,R=m;
while(L<R){
int mid=L+R+>>;
if(check(mid))L=mid;
else R=mid-;
}
printf("%d\n",L);
}
return ;
}
hdu3715
然后poj这题基本思路基本都是差不多,就是建边的时候花样变了一下,具体情况3类分析一下即可,同样注意特殊情况(同状态连边)要考虑到。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define mst(x) memset(x,0,sizeof x)
#define dbg(x) cerr << #x << " = " << x <<endl
#define dbg2(x,y) cerr<< #x <<" = "<< x <<" "<< #y <<" = "<< y <<endl
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> pii;
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,):;}
template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,):;}
template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=+,M=+;
struct stothx{int x,y,c;}Q[M];
int n,m,T;
struct thxorz{
int head[N],to[M<<],nxt[M<<],dfn[N],low[N],tim,stk[N],instk[N],bel[N],Top,scc,tot;
inline void clear(){mst(head),mst(dfn),tot=tim=scc=;}
inline void link(int x,int y){to[++tot]=y,nxt[tot]=head[x],head[x]=tot;}
void tarjan(int x){//dbg(x);
#define y to[j]
dfn[x]=low[x]=++tim,stk[++Top]=x,instk[x]=;
for(register int j=head[x];j;j=nxt[j]){
if(!dfn[y])tarjan(y),MIN(low[x],low[y]);
else if(instk[y])MIN(low[x],dfn[y]);
}
if(dfn[x]==low[x]){
int tmp;++scc;
do instk[tmp=stk[Top--]]=,bel[tmp]=scc;while(tmp^x);
}
#undef y
}
inline bool check(){
for(register int i=;i<=n;++i)if(bel[i]==bel[i+n])return ;
return ;
}
}G;
int bel[N],id[N],a[M],b[M];
inline bool check(int mid){//dbg(mid);
G.clear();
for(register int i=;i<=mid;++i){
int x=bel[a[i]],y=bel[b[i]],xi=id[a[i]],yi=id[b[i]];
if(a[i]==b[i])xi?G.link(x,x+n):G.link(x+n,x);
else if(x^y)G.link(xi?x:x+n,yi?y+n:y),G.link(yi?y:y+n,xi?x+n:x);
}
for(register int i=;i<=n<<;++i)if(!G.dfn[i])G.tarjan(i);
return G.check();
} int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
while(read(n),read(m),n||m){
for(register int i=,x,y;i<=n;++i){
read(x),read(y);
bel[x]=bel[y]=i,id[x]=,id[y]=;
}
for(register int i=;i<=m;++i)read(a[i]),read(b[i]);
int L=,R=m;
while(L<R){
int mid=L+R+>>;
if(check(mid))L=mid;
else R=mid-;
}
printf("%d\n",L);
}
return ;
}
poj2723
hdu3715 Go Deeper[二分+2-SAT]/poj2723 Get Luffy Out[二分+2-SAT]的更多相关文章
- 【POJ2723】Get Luffy Out - 二分+2-SAT
题面描述 Ratish is a young man who always dreams of being a hero. One day his friend Luffy was caught by ...
- poj2723 2sat判断解+二分
典型的2-sat问题,题意:有m个门,每个门上俩把锁,开启其中一把即可,现在给n对钥匙(所有 钥匙编号0123456...2n-1),每对钥匙只能用一把,要求尽可能开门多(按顺序,前max个). 关键 ...
- POJ2723 Get Luffy Out解题报告tarjan+2-SAT+二分
今天看到讲2-SAT比较好的blog,感觉微微的理解了2-SAT 传送门 参考: https://blog.csdn.net/leolin_/article/details/6680144 题意:你有 ...
- HDU - 1816 Get Luffy Out *(二分 + 2-SAT)
题目大意:有N串钥匙,M对锁.每串钥匙仅仅能选择当中一把.怎样选择,才干使开的锁达到最大(锁仅仅能按顺序一对一对开.仅仅要开了当中一个锁就可以) 解题思路:这题跟HDU - 3715 Go Deepe ...
- poj 2723 Get Luffy Out 二分+2-sat
题目链接 给n个钥匙对, 每个钥匙对里有两个钥匙, 并且只能选择一个. 有m扇门, 每个门上有两个锁, 只要打开其中一个就可以通往下一扇门. 问你最多可以打开多少个门. 对于每个钥匙对, 如果选择了其 ...
- 二分答案:Poweroj2461-入门基础之二分答案(二分法的应用)
传送门:点击打开链接 入门基础之二分答案 Time Limit: 1000 MS Memory Limit: 65536 KBTotal Submit: 179 Accepted: 33 Page V ...
- POJ2723 Get Luffy Out 【2-sat】
题目 Ratish is a young man who always dreams of being a hero. One day his friend Luffy was caught by P ...
- POJ3189二分最大流(枚举下界,二分宽度,最大流判断可行性)
题意: 有n头猪,m个猪圈,每个猪圈都有一定的容量(就是最多能装多少只猪),然后每只猪对每个猪圈的喜好度不同(就是所有猪圈在每个猪心中都有一个排名),然后要求所有的猪都进猪圈,但是要求所有 ...
- hdu2289Cup(神坑题,精度+二分,以半径二分不能过,以高度为二分就过了)
Problem Description The WHU ACM Team has a big cup, with which every member drinks water. Now, we kn ...
随机推荐
- codevs 1048/洛谷 1880:石子归并
题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使 ...
- thinkphp5相关
THINKPHP5代码风格规范(基于PSR): https://www.jianshu.com/p/e53d26407e68
- oracle——学习之路(select检索)
select语法: select [distinct|all] 列名 from 表名 [where] [group by] [having] [order ...
- 在springMVC框架中集成quartz作业调度器
1.首先需要导入这几个jar包,如下图: 其中log4j,quartz,slf4j-api,slf4j-log4j12我是在项目中都引用了 2.引用完jar包后,新建一个作业调度类,执行作业调度逻辑, ...
- win10从零安装eclipse并配置SVN和Maven
原因:公司的新电脑,重新安装eclipse并通过SVN检入项目,中间经历了各种坎坷,终于在周五配置项目并启动成功:在此记录一下,给后来人以警戒,同时自己也可以常温常新. 刚开始安装的是eclipse4 ...
- if (strAreaCode.Find("体检")>=0)
string类提供了6种查找函数,每种函数以不同形式的find命名. 这些操作全部返回string::size_type类型的值,以下形式标记查找匹配所发生的位置: 或者返回一个名为string::n ...
- 什么是Sprint?
Sprint指Scrum团队完成一定数量工作所需的短暂.固定的周期.Sprint是Scrum和敏捷的核心,找到正确的Sprint周期将帮助您的敏捷团队交付更高质量的产品. “在Scrum框架中,庞大且 ...
- Linux Centos7 离线安装docker 【官网翻译和注释】
Centos7的Docker安装 需要一个维护版本的centos7,所以6不行. 卸载旧版本 旧版本的docker被称为 docker or docker-engine 如果存在请删除它们. sudo ...
- Web API 自动生成接口文档
1.添加NuGet程序包 Microsoft ASP.NET Web API 2.2 Help Page (这是微软官方的) A Simple Test Client for ASP.NET ...
- Django2.0 应用 Xadmin 报错解决(转载)
原文地址:https://blog.csdn.net/GoAheadNeverTurnBack/article/details/8143362 1.TypeError at /xadmin/ l ...