题目大意:
有n个数,分别为0,1。
有m个表达式告诉你 第i个数和第j个数 经过 and 或者 or 或者 xor 运算 得到的结果,问你能否构造出一个合适的n个数。
解题思路:
2-SAT模型,每个数只有0,1。
那么接下来的问题其实只有如何建图的问题 详细建图在代码中。
我们以i表示0 i+n表示1
Ac代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn=2e3+5;
const int INF=1e9+7;
int n,m;
vector<int> v[maxn];
int tot,cnt,low[maxn],dfn[maxn],belong[maxn];
bool vis[maxn];
stack<int> s;
void tarjan(int u)
{
low[u]=dfn[u]=++tot;
s.push(u),vis[u]=1;
for(int i=0;i<v[u].size();i++)
{
int now=v[u][i];
if(!dfn[now])
{
tarjan(now);
low[u]=min(low[u],low[now]);
}
else if(vis[now])
low[u]=min(low[u],dfn[now]);
}
if(dfn[u]==low[u])
{
cnt++;
while(!s.empty())
{
int now=s.top();
vis[now]=0,s.pop();
belong[now]=cnt;
if(now==u) break;
}
}
}
bool check() //判断合法性
{
for(int i=1;i<=n;i++)
if(belong[i]==belong[i+n]) return 0;
return 1;
}
void add(int x,int y)
{
v[x].push_back(y);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y,z;
string op;
scanf("%d%d%d",&x,&y,&z);
x++,y++;
cin>>op;
if(op=="AND")
{
if(z==1) add(x,x+n),add(y,y+n); //表示x y必须都为1
if(z==0) add(x+n,y),add(y+n,x); //表示一个若为1 另一个必定为0
}
if(op=="OR")
{
if(z==1) add(x,y+n),add(y,x+n); //表示一个若为0 另一个必定为1
if(z==0) add(x+n,x),add(y+n,y); //表示x y必须都为0
}
if(op=="XOR")
{
if(z==1) add(x,y+n),add(y,x+n); //表示一个为0 另一个必须为1
if(z==0) add(x,y),add(x+n,y+n); //必须同时是0 或者同时是1
}
}
for(int i=1;i<=2*n;i++) //缩点
if(!dfn[i]) tarjan(i);
if(check()) printf("YES\n");
else printf("NO\n");
//system("pause");
return 0;
}