题目:
题解:
那么我们的两种选择就是选0/1
这里我们见到了新的模型:必选
(A,B)
,只需要
A′−>A
B′−>B
注意不能光考虑AND的1的情况,如果是0还有一个限制,不能取(1,1)
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int N=5005;
const int M=1000005;
int tot,nxt[M*4],point[N],v[M*4],dfn[N],low[N],stack[N],top,id,nn,belong[N];bool vis[N];
void addline(int x,int y){++tot; nxt[tot]=point[x]; point[x]=tot; v[tot]=y;}
void tarjan(int x)
{
low[x]=dfn[x]=++nn; vis[x]=1; stack[++top]=x;
for (int i=point[x];i;i=nxt[i])
if (!dfn[v[i]])
{
tarjan(v[i]);
low[x]=min(low[x],low[v[i]]);
}else if (vis[v[i]]) low[x]=min(low[x],dfn[v[i]]);
if (low[x]==dfn[x])
{
int now=0;++id;
while (now!=x)
{
now=stack[top--];
vis[now]=0;
belong[now]=id;
}
}
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for (int i=1;i<=m;i++)
{
int x,y,z;char st[5];
scanf("%d%d%d",&x,&y,&z);scanf("%s",st);
++x;++y;
if (st[0]=='A')
{
if (z==1)//必须同时选1
{addline(x,x+n);addline(y,y+n);}
else //不能同时取(1,1)
{addline(x+n,y);addline(y+n,x);}
}
else if (st[0]=='O')
{
if (z==0)
{addline(x+n,x);addline(y+n,y);}
else {addline(x,y+n);addline(y,x+n);}
}
else
{
if (z==0)//(0,0)/(1,1)要么都取要么都不取
{
addline(x,y); addline(y,x);
addline(x+n,y+n); addline(y+n,x+n);
}
else//(0,1)/(1,0)要么都取要么都不取
{
addline(x,y+n); addline(y+n,x);
addline(x+n,y); addline(y,x+n);
}
}
}
for (int i=1;i<=2*n;i++)
if (!dfn[i]) tarjan(i);
for (int i=1;i<=n;i++)
if (belong[i]==belong[i+n]) {printf("NO");return 0;}
printf("YES");
}