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 ...
随机推荐
- bootstrap基础学习【网格系统】(三)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- textarea文本域轻松实现高度自适应
转载:http://www.xuanfengge.com/textarea-on-how-to-achieve-a-high-degree-of-adaptive.html 今天需要些一个回复评论的页 ...
- java知识随笔整理-数据库的临时表
1.创建临时表的方法 方法一.select * into #临时表名 from 你的表; 方法二. create table #临时表名(字段1 约束条件,字段2 约束条件,.....)create ...
- System memory 259522560 must be at least 4.718592
[学习笔记] /*没有下面的话, 会报一个错误,java.lang.IllegalArgumentException: System memory 259522560 must be at least ...
- Go语言注意事项
必须恰当导入需要的包,缺少了必要的包或者导入了不需要的包,程序都无法编译通过.这项严格要求避免了程序开发过程中引入未使用的包(译注:Go语言编译过程没有警告信息,争议特性之一 import 声明必须跟 ...
- PHP获取指定时间的前6个月月份 、获取前6天日期
//获取前6个月月份 public function to_sex_month(){ $today = input('param.today') ? input('param.today') : da ...
- Java 抽象类详解
在<Java中的抽象方法和接口>中,介绍了抽象方法与接口,以及做了简单的比较. 这里我想详细探讨下抽象类. 一.抽象类的定义 被关键字“abstract”修饰的类,为抽象类.(而且,abx ...
- Java并发与多线程教程(2)
Java同步块 Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java同步块用来避免竞争.本文介绍以下内容: Java同步关键字(synchronzied) ...
- springboot打包war包部署到tomcat
1.pom.xml修改处 <modelVersion>4.0.0</modelVersion><groupId>com.xx</groupId>< ...
- Django多对多
表名小写+_set() 得到的是一个QuertSet集合,她的后面可以跟 .add() .remove() .update() .clear() models.py 文件 # 学生表 ...