题目

Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integer c (0 ≤ c ≤ 1). One Katu is solvable if one can find each vertex Vi a value Xi (0 ≤ Xi ≤ 1) such that for each edge e(a, b) labeled by op and c, the following formula holds:

Xa op Xb = c

The calculating rules are:

AND 0 1

0 0 0

1 0 1

OR 0 1

0 0 1

1 1 1

XOR 0 1

0 0 1

1 1 0

Given a Katu Puzzle, your task is to determine whether it is solvable.

输入格式

The first line contains two integers N (1 ≤ N ≤ 1000) and M,(0 ≤ M ≤ 1,000,000) indicating the number of vertices and edges.

The following M lines contain three integers a (0 ≤ a < N), b(0 ≤ b < N), c and an operator op each, describing the edges.

输出格式

Output a line containing "YES" or "NO".

输入样例

4 4

0 1 1 AND

1 2 1 OR

3 2 0 AND

3 0 0 XOR

输出样例

YES

提示

X0 = 1, X1 = 1, X2 = 0, X3 = 1.

题解

跪了。。。就因为n << 1写成了1 << n QAQ

这题加深了我对2-sat建图的理解,建边就表示选择了起点就必须选择终点

对于每个限制条件,我们分别考虑选择x的不同值

AND

为1,则x0->x1,y0->y1,让x0,y0自相矛盾,无法选择

为0,则x0->y1,y0->x1

OR

为1,则x0->y1,y0->x1

为0,则x1->x0,y1->y0

XOR

为1,则x0->y1,x1->y0,y1->x0,y0->x1

为0,则x0->y0,x1->y1,y0->x0,y1->x1

tarjan判断一下x0和x1是否在同一个强联通分量即可

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define cls(x) memset(x,0,sizeof(x))
using namespace std;
const int maxn = 4005,maxm = 4000005,INF = 1000000000;
int n,m,h[maxn],ne;
struct EDGE{int to,nxt;}ed[maxm];
void build(int u,int v){ed[ne] = (EDGE){v,h[u]}; h[u] = ne++;}
int dfn[maxn],low[maxn],Scc[maxn],st[maxn],scci,top,cnt;
void dfs(int u){
dfn[u] = low[u] = ++cnt;
st[++top] = u;
Redge(u){
if (!dfn[to = ed[k].to]){
dfs(to);
low[u] = min(low[u],low[to]);
}else if (!Scc[to]) low[u] = min(low[u],dfn[to]);
}
if (dfn[u] == low[u]){
scci++;
do{Scc[st[top]] = scci;}while (st[top--] != u);
}
}
char opt[10];
int main(){
while (~scanf("%d%d",&n,&m)){
int a,b,v,x0,x1,y0,y1; cnt = scci = top = 0; ne = 1;
cls(dfn); cls(h); cls(Scc); cls(low);
while (m--){
scanf("%d%d%d%s",&a,&b,&v,opt);
x0 = a << 1; x1 = x0 | 1; y0 = b << 1; y1 = y0 | 1;
if (opt[0] == 'A'){
if (v) build(x0,x1),build(y0,y1);
else build(x1,y0),build(y1,x0);
}
else if (opt[0] == 'O'){
if (v) build(x0,y1),build(y0,x1);
else build(x1,x0),build(y1,y0);
}
else if (opt[0] == 'X'){
if (v) build(x0,y1),build(y0,x1),build(x1,y0),build(y1,x0);
else build(x1,y1),build(y0,x0),build(x0,y0),build(y1,x1);
}
}
for (int i = 0; i < 2 * n; i++) if (!dfn[i]) dfs(i);
bool flag = true;
for (int i = 0; i < n; i++)
if (Scc[i << 1] == Scc[i << 1 | 1]){
flag = false; break;
}
if (flag) printf("YES\n");
else printf("NO\n");
}
return 0;
}

最新文章

  1. mongodb(Index)
  2. 【吉光片羽】MVC 导出Word的两种方式
  3. ${pageContext.request.contextPath}无效
  4. RecyclerView解析--onViewDetachedFromWindow()/onViewAttachedToWindow()
  5. 《GK101任意波发生器》升级固件发布(版本:1.0.2build955)
  6. paper 53 :深度学习(转载)
  7. 从一次异常中浅谈Hibernate的flush机制
  8. 修改zepto源代码,使支持wp8的ie10
  9. Stbdroid之ShapeDrawable
  10. Visual Studio 2013发布Cloud Service至Azure China
  11. 故障排查实战案例——某电器ERP系统日志暴增
  12. 模拟Struts2框架Action的实现
  13. top和nvidia-smi无法显示占用GPU的PID问题
  14. 向后台提交数据:cookie,secure_cookie,
  15. css td hover 选择器无效
  16. 20155219 2016-2017-2《Java程序设计》课程总结
  17. c#中委托与事件
  18. 洛谷P2633 Count on a tree(主席树,倍增LCA,树上差分)
  19. IAR EWARM 字体设置
  20. ELK学习笔记之ElasticSearch简介

热门文章

  1. 3219: 求最高同学位置—C语言版
  2. fifo - 先进先出的特殊文件, 又名管道
  3. python基础一 day17 作业
  4. ZJOI2004 午餐
  5. 成员变量(实例变量)&amp;局部变量&amp;静态变量(类变量)的区别
  6. LeetCode946-验证栈序列
  7. The Apache Tomcat Servlet/JSP Container
  8. mysql索引详细描述与应用场景
  9. 扩展程序 - Google Chrome
  10. mac terminal基本命令