题目大意
给定n个布尔型变量,以及m个限制,限制有三种类型,AND,OR,XOR。分别表示两个变量进行这些运算的值。每个变量只能取0或1.问是否有一种情况满足所有条件的限制
分析
对于本题,设i表示该变量为false,i’表示该变量为true。
i and j=1-------------->add(i,i') add(j,j')
i and j=0-------------->add(i',j) add(j',i)
i or j=1---------------->add(i,j') add(j,i')
i or j=0---------------->add(i',i) add(j',j)
i xor j=1--------------->add(i',j) add(j',i) add(i,j') add(j,i')
i xor j=0---------------> add(i,j) add(i',j') add(j,i) add(j',i')
连一条边i->j表示若选i则必选j。
根据2—Sat然后求一次强联通分量,若有i、i'在同一强联通分量内则无满足条件,反之则有。
代码
type
arr=record
x,y,next:longint;
end;
var
a:array[1..5000000] of arr;
f:array[1..3000] of boolean;
ls,zan,g:array[1..3000] of longint;
dfn,low:array[1..3000] of longint;
tot,sum,n,m:longint;
i,j,k:longint;
e,d:longint;
x,y,z:longint;
c:char;
procedure add(x,y:longint);
begin
inc(e);
a[e].x:=x;
a[e].y:=y;
a[e].next:=ls[x];
ls[x]:=e;
end;
function min(x,y:longint):longint;
begin
if x<y then exit(x)
else exit(y);
end;
procedure dfs(x:longint);
var
i:longint;
begin
inc(d);
dfn[x]:=d;
low[x]:=d;
inc(tot);
zan[tot]:=x;
f[x]:=true;
i:=ls[x];
while i>0 do
with a[i] do
begin
if dfn[y]=0
then begin
dfs(y);
low[x]:=min(low[x],low[y]);
end
else if f[y] then low[x]:=min(low[x],dfn[y]);
i:=next;
end;
if low[x]=dfn[x] then
begin
inc(sum);
repeat
i:=zan[tot];
dec(tot);
f[i]:=false;
g[i]:=sum;
until i=x;
end;
end;
procedure tarjan;
var
i:longint;
begin
fillchar(f,sizeof(f),0);
for i:=1 to n*2 do
if dfn[i]=0
then
dfs(i);
end;
procedure work;
var
i:longint;
begin
for i:=1 to n do
if g[i]=g[i+n] then
begin
writeln('NO');
exit;
end;
writeln('YES');
end;
begin
readln(n,m);
for i:=1 to m do
begin
read(x,y,z);
inc(x); inc(y);
read(c);
while c=' ' do
read(c);
readln;
if c='A' then
if z=1
then
begin
add(x,x+n);
add(y,y+n);
end
else
begin
add(x+n,y);
add(y+n,x);
end;
if c='O' then
if z=1
then
begin
add(x,y+n);
add(y,x+n);
end
else
begin
add(x+n,x);
add(y+n,y);
end;
if c='X' then
if z=1
then
begin
add(x,y+n);
add(x+n,y);
add(y,x+n);
add(y+n,x);
end
else
begin
add(x,y);
add(x+n,y+n);
add(y,x);
add(y+n,x+n);
end;
end;
tarjan;
work;
end.