有N个变量X1X1~XNXN,每个变量的可能取值为0或1。

给定M个算式,每个算式形如 XaopXb=cXaopXb=c,其中 a,b 是变量编号,c 是数字0或1,op 是 and,or,xor 三个位运算之一。

求是否存在对每个变量的合法赋值,使所有算式都成立。

输入格式

第一行包含两个整数N和M。

接下来M行,每行包含三个整数a b c,以及一个位运算(AND,OR,XOR中的一个)。

输出格式

输出结果,如果存在,输出“YES”,否则输出“NO”

数据范围

1≤N≤10001≤N≤1000,
1≤M≤1061≤M≤106

输入样例:

4 4
0 1 1 AND
1 2 1 OR
3 2 0 AND
3 0 0 XOR

输出样例:

YES

思路:根据题意,该题是一个 2-SAT 问题,将操作符进行转换,进行判定即可

对于 A[x],可以通过连边 <x',x> 实现,NOT A[x],可以通过连边 <x,x'> 来实现,对于 NOT(A[x] AND A[y]) 需要连两条边 <x, y'> 和 <y, x'> 来实现,对于 A[x] OR A[y] 需要连两条边 <x', y> 和 <y', x> 来实现

故对于 and、or、xor 三种运算有:

and 运算:

a and b = 0 时:若 a=1,则必定满足 b=0;若 b=1,则必定满足 a=0,即:<a,1,b,0>、<b,1,a,0>
a and b = 1 时:a=1 且 b=1,即:<a,0,a,1>、<b,0,b,1>
or 运算:

a or b = 0 时:a = 0 且 b = 0,即:<a,1,a,0>、<b,1,b,0> 
a or b = 1 时:若 a=0,则必定满足 b=1;若 b=0,则必定满足 a=0,即:<a,0,b,1>、<b,0,a,1>
xor 运算:

a xor b = 0 时,有以下四种情况:
若 a = 0,则必定满足 b = 0,即:<a,0,b,0>
若 b = 0,则必定满足 a = 0,即:<b,0,a,0>
若 a = 1,则必定满足 b = 1,即:<a,1,b,1>
若 b = 1,则必定满足 a = 1,即:<b,1,a,1>
a xor b = 1 时,有以下四种情况:
若 a = 0,则必定满足 b = 1,即:<a,0,b,1>
若 b = 0,则必定满足 a = 1,即:<b,0,a,1>
若 a = 1,则必定满足 b = 0,即:<a,1,b,0>
若 b = 1,则必定满足 a = 0,即:<b,1,a,0>

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring> using namespace std;
#define debug(x) cout << "fuck bug " << x << "\n";
#define ios ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
const int maxn = 4e5 + ;
typedef long long ll; int n,m; struct edge
{
int to,nxt;
}e[maxn]; int head[maxn],tot;
void add(int u ,int v){
e[++tot].to = v;
e[tot].nxt = head[u];
head[u] = tot;
} int dfn[maxn],low[maxn],num,inStack[maxn];
int stack[maxn],top,cnt,C[maxn];
void tarjan(int x) {
dfn[x] = low[x] = ++num;
stack[++top] = x; inStack[x] = true;
for (int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if (dfn[y] == ) {
tarjan(y);
low[x] = min(low[x], low[y]);
} else if (inStack[y]) {
low[x] = min(low[x], low[y]);
}
}
if (low[x] == dfn[x]) {
cnt++;
int z;
do {
z = stack[top--];
inStack[z] = false;
C[z] = cnt;
} while (z != x);
}
} int main(int argc, char const *argv[])
{
//cin >> n >> m;
scanf("%d %d",&n,&m);
for(int i = ;i <= m ; i ++){
int a , b , c ; char str[];
//cin >> a >> b >> c >> str;
scanf("%d %d %d %s",&a,&b,&c,str);
if(str[] == 'A'){
if(c == ){
add(a,a+n);
add(b,b+n);
}else{
add(a+n,b);
add(b+n,a);
}
}else if(str[] == 'O'){
if(c == ){
add(a,b+n);
add(b,a+n);
}else{
add(a+n,a);
add(b+n,b);
}
}else if(str[] == 'X'){
if(c == ){
add(a,b+n);
add(b,a+n);
add(a+n,b);
add(b+n,a);
}else{
add(a,b);
add(b,a);
add(a+n,b+n);
add(b+n,a+n);
}
}
} for(int i = ;i < n + n; i++){
if(!dfn[i]) tarjan(i);
} bool flag=;
for(int i = ;i < n ;i ++){
if(C[i] == C[i + n]) {
flag = ;
break;
}
} if(flag) puts("YES");
else puts("NO"); return ;
}

Katu Puzzle POJ - 3678 (2 - sat)的更多相关文章

  1. Katu Puzzle POJ - 3678(水2 - sat)

    题意: 有n个未知量,m对未知量之间的关系,判断是否能求出所有的未知量且满足这些关系 解析: 关系建边就好了 #include <iostream> #include <cstdio ...

  2. M × N Puzzle POJ - 2893(奇数码)

    The Eight Puzzle, among other sliding-tile puzzles, is one of the famous problems in artificial inte ...

  3. POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang

    Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...

  4. 学习笔记(two sat)

    关于two sat算法 两篇很好的论文由对称性解2-SAT问题(伍昱), 赵爽 2-sat解法浅析(pdf). 一些题目的题解 poj 3207 poj 3678 poj 3683 poj 3648 ...

  5. poj 3335(半平面交)

    链接:http://poj.org/problem?id=3335     //大牛们常说的测模板题 ------------------------------------------------- ...

  6. poj 3122 (二分查找)

    链接:http://poj.org/problem?id=3122 Pie Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1 ...

  7. poj3270 && poj 1026(置换问题)

    | 1 2 3 4 5 6 | | 3 6 5 1 4 2 | 在一个置换下,x1->x2,x2->x3,...,xn->x1, 每一个置换都可以唯一的分解为若干个不交的循环 如上面 ...

  8. POJ——3169Layout(差分约束)

    POJ——3169Layout Layout Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14702   Accepted ...

  9. POJ 3252 (数位DP)

    ###POJ 3252 题目链接 ### 题目大意:给你一段区间 [Start,Finish] ,在这段区间中有多少个数的二进制表示下,0 的个数 大于等于 1 的个数. 分析: 1.很显然是数位DP ...

随机推荐

  1. 使用django uwsgi 导致磁盘满

    lsof |grep delete |sort -nrk 7|more kill 掉这些进程

  2. QT Embedded二三事之QObject的元对象

    一.元对象  元对象被称做是meta object.在运行时刻(runtime),能够提供对象的运行时信息.        在C++语言发展的早期,C++语言本身没有定义对象的运行时信息,如输出类的名 ...

  3. 用Python写一个将Python2代码转换成Python3代码的批处理工具

    之前写过一篇如何在windows操作系统上给.py文件添加一个快速处理的右键功能的文章:<一键将Python2代码自动转化为Python3>,作用就是为了将Python2的文件升级转换成P ...

  4. Flutter移动电商实战 --(7)dio基础_POST请求的使用

    这节学习一下POST请求的使用,其实POST和Get请求都是在工作中最重要的两种请求.比如我们要传递一组表单数据过去,这时候用Get请求就是不太合适的,使用POST比较好. SingleChildSc ...

  5. ansible的剧本

    ansible的playbook的介绍-yaml ansible的playbook是使用yaml语言写的 YAML标记语言介绍YAML是一个可读性高的用来表达资料序列的格式.YAML参考了其他多种语言 ...

  6. vs2017+opencv配置参考链接

    本人通过以下几篇博客完成vs2017+opencv3.4.1的配置: OpenCV 3.4.1 + VS2017 开发环境搭建 - 简书 WIN10下 VS2017+OpenCv 3.4.1 配置 - ...

  7. ubuntu下如何使用dpkg删除某个软件包?

    答:步骤如下: 1. 找出包名 dpkg -l |grep <package name> 2. 卸载 dpkg -r <package name>

  8. Tween(补间)动画

    视图动画,也叫Tween(补间)动画可以在一个视图容器内执行一系列简单变换(位置.大小.旋转.透明度).譬如,如果你有一个TextView对象,您可以移动.旋转.缩放.透明度设置其文本,当然,如果它有 ...

  9. pipreqs------查找python项目依赖并生成requirement

    一起开发项目的时候总是要搭建环境和部署环境的,这个时候必须得有个python第三方包的list,一般都叫做requirements.txt. 如果一个项目使用时virtualenv环境,还好办 pip ...

  10. smarty section 循环不同的四个样式

    <div class="moban_spzs"> <{section name=goodslist loop=$strdata6}> <{if $sm ...