[2-sat]模型基础(poj3678)
来源:互联网 发布:php运费模板源码 编辑:程序博客网 时间:2024/06/13 04:04
2-sat入门
sat问题是计算机科学的历史上一个非常著名的NPC问题。指的是,任何一个逻辑表达式都可以化简成为一个析取范式,而证明这个逻辑表达式是否可解。
解题的方法
这是一个图论的问题,而一般使用这样的解题方法;
对于一个逻辑变量p,如果
对于一个合取式(p+q),我们知道,如果p=0,则q=1,q=0,p=1,所以我们将一个逻辑变量看作两个点,一个是其本身,另一个是其反变量,如果p可以推出q,则在两个点之间连接一条边。
然后,使用tarjan算法,判断相同逻辑变量所代表的两个点是否在同一个强连通分量当中,最后得到相关的解。
一个例题
poj3678裸的2-sat模型,代码附上
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<vector>#include<stack>using namespace std;#define MAXN 2005struct Edge{ int to; int next;}EdgeTable[MAXN*MAXN];int dfn[MAXN],low[MAXN];int head[MAXN];int state[MAXN],match[MAXN];int n,m,e,cnt,curT;stack<int>S;void addEdge(int from,int to){ EdgeTable[e].to=to; EdgeTable[e].next=head[from]; head[from]=e++;}void Init(){ cnt=e=0; memset(dfn,-1,sizeof(dfn)); memset(low,-1,sizeof(low)); memset(state,0,sizeof(state)); memset(head,-1,sizeof(head));}void processAND(int a,int b,int c){ if(c==1){ addEdge(a*2,b*2); addEdge(a*2,b*2+1); addEdge(a*2+1,b*2+1); addEdge(b*2,a*2); addEdge(b*2,a*2+1); addEdge(b*2+1,a*2+1); } else{ addEdge(a*2+1,b*2); addEdge(b*2+1,a*2); }}void processOR(int a,int b,int c){ if(c==1){ addEdge(a*2,b*2+1); addEdge(b*2,a*2+1); } else{ addEdge(a*2,b*2); addEdge(b*2+1,a*2); addEdge(a*2+1,b*2+1); addEdge(b*2,a*2); addEdge(a*2+1,b*2); addEdge(b*2+1,a*2+1); }}void processXOR(int a,int b,int c){ if(c==0){ addEdge(a*2,b*2); addEdge(a*2+1,b*2+1); addEdge(b*2,a*2); addEdge(b*2+1,a*2+1); } else{ addEdge(a*2,b*2+1); addEdge(a*2+1,b*2); addEdge(b*2,a*2+1); addEdge(b*2+1,a*2); }}void get_Graph(){ int i,a,b,c; char str[5]; for(i=0;i<m;i++){ scanf("%d%d%d%s",&a,&b,&c,str); if(str[0]=='A') processAND(a,b,c); else if(str[0]=='O') processOR(a,b,c); else processXOR(a,b,c); } return;}void Dfs(int cur){ dfn[cur]=low[cur]=curT++; state[cur]=1; S.push(cur); int i; for(i=head[cur];i!=-1;i=EdgeTable[i].next){ int dest = EdgeTable[i].to; if(state[dest]==1) low[cur] = min(low[cur],low[dest]); else if(!state[dest]){ Dfs(dest); low[cur] = min(low[cur],low[dest]); } } if(dfn[cur] == low[cur]){ while(!S.empty()){ int d = S.top(); S.pop(); state[d]=2; match[d]=cnt; if(d==cur)break; } cnt++; }}void Solve(){ int i; bool flag=true; for(i=0;i<2*n;i++){ if(!state[i]){ curT=0; Dfs(i); } } for(i=0;i<n;i++){ if(match[i*2]==match[2*i+1]){ flag=false; break; } } if(flag)printf("YES\n"); else printf("NO\n");}int main(){ //freopen("input","r",stdin); Init(); scanf("%d %d",&n,&m); get_Graph(); Solve();}
0 0
- [2-sat]模型基础(poj3678)
- 2-sat POJ3678
- poj3678 2-sat
- 2-SAT——POJ3678
- POJ3678:Katu Puzzle 2-SAT
- POJ3678 Katu Puzzle【2-SAT】
- POJ3678 HDU4421 2-sat的建边
- 2-sat(and,or,xor)poj3678
- POJ3678 Katu Puzzle (2-SAT检验)
- [POJ3678]Katu Puzzle(2-SAT)
- poj3678:Katu Puzzle(2-SAT)
- 2-SAT——1.0(hdu3062,poj3678)
- poj3678 Katu Puzzle(2-SAT+经典建图)
- POJ3678.Katu Puzzle——2-sat裸题
- POJ3678 Katu Puzzle(2-sat tanjar判矛盾)
- hdu 4421 和poj3678类似二级制操作(2-sat问题)
- POJ3678
- POJ3678
- SPOJ COT(树上k大,主席树+LCA)
- FFmpeg音视频同步的问题
- 93.leetcode Restore IP Addresses(medium)[回溯 DFS]
- MySQL for mac 连接报错:Access denied for user 'root'@'localhost' (using password: YES)
- Codeforces Round #368 (Div. 2) D Persistent Bookcase(离线+DFS)
- [2-sat]模型基础(poj3678)
- Day0823_将音乐库中的音乐在Service中异步加载, 播放音乐并设置到通知栏
- pycharm设置
- Linux USB Driver
- UVaLive 6697 (DP)
- Eclipse中写Spark代码
- AngularJS 发送POST请求到后台
- java实现简单排序算法:归并排序
- U3D 动作系统实践