标签:solution org font space xor 赋值 mic i++ lse
Description
有 N 个变量 X0 ~ XN-1,每个变量的可能取值为 0 或 1 。
给定 M 个算式,每个算式形如 Xa op Xb = c,其中 a,b 是变量编号,c 是数字 0 或 1 ,op 是 and,or,xor 三个位运算之一。
求是否存在对每个变量的合法赋值,使所有算式都成立。
输入格式
第一行包含两个整数 N 和 M 。
接下来 M 行,每行包含三个整数a b c,以及一个位运算(and,or,xor中的一个)。
输出格式
输出结果,如果存在,输出“YES”,否则输出“NO”
数据范围
1≤N≤1000,
1≤M≤1e6
Solution
每个变量只有两个可能值,且不同变量间有约束,符合2-SAT的模型。
将位运算式子转化成约束条件,例如
a and b = 0 表示
若 Xa = 1 ,则必须 Xb = 0。从 a+N 到 b 连有向边,
若 Xb = 1 ,则必须 Xa = 0。从 b+N 到 a 连有向边。
其他同理,详见代码
Code
#include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; const int N=2e3+10,M=2e6+10; int head[N],nxt[M],to[M],cnt; int n,m,a,b,c,d[N],scc; int dfn[N],low[N],tot,st[N],top; char s[10]; bool in[N]; void add(int x,int y) { to[++cnt]=y,nxt[cnt]=head[x],head[x]=cnt; } void tarjan(int u) { dfn[u]=low[u]=++cnt; st[++top]=u,in[u]=true; for(int i=head[u];i;i=nxt[i]) { int v=to[i]; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(in[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { scc++; int z; do{ z=st[top--]; in[z]=false,d[z]=scc; }while(z!=u); } } int main() { scanf("%d%d",&n,&m); while(m--) { scanf("%d%d%d%s",&a,&b,&c,s); if(s[0]==‘A‘) { if(c==0) add(a+n,b),add(b+n,a); else add(a,a+n),add(b,b+n); } else if(s[0]==‘O‘) { if(c==0) add(a+n,a),add(b+n,b); else add(a,b+n),add(b,a+n); } else if(s[0]==‘X‘) { if(c==0) add(a,b),add(b,a),add(a+n,b+n),add(b+n,a+n); else add(a,b+n),add(b,a+n),add(a+n,b),add(b+n,a); } } for(int i=1;i<=2*n;i++) if(!dfn[i]) tarjan(i); for(int i=1;i<=n;i++) if(d[i]==d[i+n]) { puts("NO"); return 0; } puts("YES"); return 0; }
标签:solution org font space xor 赋值 mic i++ lse
原文地址:https://www.cnblogs.com/hsez-cyx/p/12348492.html