这题转化一下题意就是给一堆形如$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]的更多相关文章

  1. 【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 ...

  2. poj2723 2sat判断解+二分

    典型的2-sat问题,题意:有m个门,每个门上俩把锁,开启其中一把即可,现在给n对钥匙(所有 钥匙编号0123456...2n-1),每对钥匙只能用一把,要求尽可能开门多(按顺序,前max个). 关键 ...

  3. POJ2723 Get Luffy Out解题报告tarjan+2-SAT+二分

    今天看到讲2-SAT比较好的blog,感觉微微的理解了2-SAT 传送门 参考: https://blog.csdn.net/leolin_/article/details/6680144 题意:你有 ...

  4. HDU - 1816 Get Luffy Out *(二分 + 2-SAT)

    题目大意:有N串钥匙,M对锁.每串钥匙仅仅能选择当中一把.怎样选择,才干使开的锁达到最大(锁仅仅能按顺序一对一对开.仅仅要开了当中一个锁就可以) 解题思路:这题跟HDU - 3715 Go Deepe ...

  5. poj 2723 Get Luffy Out 二分+2-sat

    题目链接 给n个钥匙对, 每个钥匙对里有两个钥匙, 并且只能选择一个. 有m扇门, 每个门上有两个锁, 只要打开其中一个就可以通往下一扇门. 问你最多可以打开多少个门. 对于每个钥匙对, 如果选择了其 ...

  6. 二分答案:Poweroj2461-入门基础之二分答案(二分法的应用)

    传送门:点击打开链接 入门基础之二分答案 Time Limit: 1000 MS Memory Limit: 65536 KBTotal Submit: 179 Accepted: 33 Page V ...

  7. 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 ...

  8. POJ3189二分最大流(枚举下界,二分宽度,最大流判断可行性)

    题意:       有n头猪,m个猪圈,每个猪圈都有一定的容量(就是最多能装多少只猪),然后每只猪对每个猪圈的喜好度不同(就是所有猪圈在每个猪心中都有一个排名),然后要求所有的猪都进猪圈,但是要求所有 ...

  9. hdu2289Cup(神坑题,精度+二分,以半径二分不能过,以高度为二分就过了)

    Problem Description The WHU ACM Team has a big cup, with which every member drinks water. Now, we kn ...

随机推荐

  1. gRPC安装的小问题

    INSTALL.md提到下述前提条件 #Pre-requisites ##Linux ```sh $ [sudo] apt-get install build-essential autoconf l ...

  2. Spark学习一:Spark概述

    1.1 什么是Spark ​ Apache Spark 是专为大规模数据处理而设计的快速通用的计算引擎. ​ 一站式管理大数据的所有场景(批处理,流处理,sql) ​ spark不涉及到数据的存储,只 ...

  3. ubuntu18下Docker运行springboot项目

    1.springboot项目打成jar包 mvn install 2.编写Dockerfile # 基础镜像使用java FROM java:8 # 作者 #MAINTAINER sk # VOLUM ...

  4. 关于日志slf4j+logback&logback.xml配置

    1.maven依赖 <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <!-- <dependen ...

  5. shell实践--简单抓取网页内容

    #!/bin/bash base_path="https://testerhome.com/"user_path="ycwdaaaa/topics?page=" ...

  6. vue的基本语法

    在学习vue之前,我们应了解一下什么是vue.js? 什么是Vue.js? Vue.js是目前最后一个前端框架,React是最流行的一个前端框架(react除了开发网站,还可以开发手机App,Vue语 ...

  7. python3启航

    Python3的基本数据类型 数字 int ,所有功能都放在int里 a1 = 123 a2 = 456 ##int 将字符串转换为数字 a = "123" print(tyep( ...

  8. User space(用户空间) 与 Kernel space(内核空间)

    出处: User space 与 Kernel space (整理)用户空间_内核空间以及内存映射 学习 Linux 时,经常可以看到两个词:User space(用户空间)和 Kernel spac ...

  9. NIPS2018最佳论文解读:Neural Ordinary Differential Equations

    NIPS2018最佳论文解读:Neural Ordinary Differential Equations 雷锋网2019-01-10 23:32     雷锋网 AI 科技评论按,不久前,NeurI ...

  10. Nopcommerce 使用Task时dbcontext关闭问题

    1.开启一个线程 Task.Run(() => { CreatPrintImage(preViewModel.DiyProductGuid); }); 2.线程代码 /// <summar ...