HDU 3715 Go Deeper(2-SAT)
来源:互联网 发布:若水软件官网 编辑:程序博客网 时间:2024/04/29 05:07
HDU 3715 Go Deeper(2-SAT)
http://acm.hdu.edu.cn/showproblem.php?pid=3715
题意:
有下面一个递归程序:
go(int dep, int n, int m)
begin
output the value of dep.
if dep < m and x[a[dep]] + x[b[dep]]!= c[dep] then go(dep + 1, n, m)
end
问你dep最多能达到什么值?由题意可知dep<=m,其中a与b与c数组都是m大小的,数组下标从0到m,然后x数组是下标从0到n-1的.且c数组的取值为0或1或2.a与b数组的取值是0到n-1.x数组的取值是0或1.
现在给出了a,b,c数组对应下标的所有值,但是还不知道x数组的取值,问你如果你来设定x的值,可以使dep最大达到多少?
分析:
由于x数组只能去0或1,可以看出该题就是2-SAT问题. 我们只要2分dep的值即可的出解.
假设当前dep=mid,然后对于下标从0到mid-1来说,有下面关系:
x[a[0]]+x[b[0]] != c[0]
x[a[1]]+x[b[1]] != c[1]
…
x[a[mid-1]]+x[b[mid-1]] !=c[mid-1]
然后我们合理的设置一下x数组的值,看看是否能满足这前mid个条件.由于a,b,c数组的值都已经知道了,比如 a[0]=1,b[0]=2,c[0]=2
有x[1]+x[2] !=2 ,那么我们可以推出边: add_clause(1,1,2,0)且 add_clause(2,1,1,0).
一般性结论有:
x[a]+x[b]= 0 -> add(a,0,b,1) add(b,0,a,1)
x[a]+x[b]=1 ->add(a,1,b,1) add(a,0,b,0) add(b,1,a,1)add(b,0,a,0)
x[a]+x[b]=2 ->add(a,1,b,0) add(b,1,a,0)
二分dep,建图2-SAT,直接解决.
AC代码:
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;const int maxn= 200 +10;const int maxm= 10000+10;int n,m;int a[maxm],b[maxm],c[maxm];struct TwoSAT{ int n; vector<int> G[maxn*2]; int S[maxn*2],c; bool mark[maxn*2]; bool dfs(int x) { if(mark[x^1]) return false; if(mark[x]) return true; mark[x]=true; S[c++]=x; for(int i=0;i<G[x].size();i++) if(!dfs(G[x][i])) return false; return true; } void init(int n) { this->n = n; for(int i=0;i<2*n;i++) G[i].clear(); memset(mark,0,sizeof(mark)); } void add_clause(int x,int xval,int y,int yval) { x=x*2+xval; y=y*2+yval; G[x].push_back(y); } bool solve() { for(int i=0;i<2*n;i+=2) if(!mark[i] && !mark[i+1]) { c=0; if(!dfs(i)) { while(c>0) mark[S[--c]]=false; if(!dfs(i+1)) return false; } } return true; }}TS;bool ok(int mid){ TS.init(n); for(int i=0;i<mid;i++) { if(c[i]==0) { TS.add_clause(a[i],0,b[i],1); TS.add_clause(b[i],0,a[i],1); } else if(c[i]==1) { TS.add_clause(a[i],0,b[i],0); TS.add_clause(a[i],1,b[i],1); TS.add_clause(b[i],0,a[i],0); TS.add_clause(b[i],1,a[i],1); } else if(c[i]==2) { TS.add_clause(a[i],1,b[i],0); TS.add_clause(b[i],1,a[i],0); } } return TS.solve();}int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0;i<m;i++) scanf("%d%d%d",&a[i],&b[i],&c[i]); int L=0,R=m; while(R>L) { int mid = L+(R-L+1)/2; if(ok(mid)) L=mid; else R=mid-1; } printf("%d\n",L); } return 0;}
- 2-sat->HDU 3715 Go Deeper
- HDU 3715 Go Deeper(2-SAT)
- 【HDU】3715 Go Deeper 2-sat
- HDU 3715 Go Deeper(2-sat)
- HDU 3715 Go Deeper 二分 + 2-sat
- HDU 3715 Go Deeper【2-SAT+二分】
- hdu 3715 Go Deeper(二分+2-sat判定)
- HDU 3715 Go Deeper(2-SAT + 二分判定)
- HDU 3715 Go Deeper(2-SAT + 二分)
- HDU - 3715 Go Deeper (二分 + 2-SAT)
- HDU 3715 Go Deeper 2-SAT 二分答案
- HDU 3715 Go Deeper(二分+2-SAT总结)
- hdu 3715 Go Deeper
- HDOJ 3715 Go Deeper (2Sat: 二分答案判定)
- HDOJ 3715 - Go Deeper 二分+2-sat判断
- hdoj 3715 Go Deeper 【2-sat 判断可行解 + 二分】
- 二分+2SAT zoj3422 Go Deeper
- hdu3715 Go Deeper--二分 & 2-sat
- Unable to execute dex: Multiple dex files define 解决方法
- Class类文件结构
- 不要迷信神话
- 一个简单推广
- 拒绝Float!
- HDU 3715 Go Deeper(2-SAT)
- Java内存区域与内存溢出
- 网络协议头部详解及结构体定义
- 汉字转化为拼音 使用pinyin4j
- java编程思想笔记——第三章&&第四章
- 交通灯管理系统学习
- 温故知新之android设备的横竖屏切换
- qsort的使用
- Oracle中REGEXP_SUBSTR函数 .