POJ 3678

Katu Puzzle










Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 7391   Accepted: 2717

Description

Katu Puzzle is presented as a directed
graph G(VE) 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 ≤ X
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.

Input

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 (0
≤ a < N), b(0
≤ b < N), c and an
operator op each, describing the edges.

Output

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

Sample Input

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

Sample Output

YES

Hint

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

Source

POJ
Founder Monthly Contest – 2008.07.27
, Dagger

2-sat

  1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <algorithm>
5 #include <stack>
6
7 using namespace std;
8
9 const int MAX_N = 1005;
10 const int edge = 1e6 + 5;
11 int first[2 * MAX_N],Next[4 * edge],v[4 * edge];
12 int N,M,dfs_clock,scc_cnt;
13 int low[2 * MAX_N],pre[2 * MAX_N],cmp[2 * MAX_N];
14 stack<int > S;
15
16 void dfs(int u) {
17 low[u] = pre[u] = ++dfs_clock;
18 S.push(u);
19 for(int e = first[u]; e != -1; e = Next[e]) {
20 if(!pre[ v[e] ]) {
21 dfs(v[e]);
22 low[u] = min(low[u],low[ v[e] ]);
23 } else {
24 if(!cmp[ v[e] ]) {
25 low[u] = min(low[u],pre[ v[e] ]);
26 }
27 }
28 }
29
30 if(pre[u] == low[u]) {
31 ++scc_cnt;
32 for(;;) {
33 int x = S.top(); S.pop();
34 cmp[x] = scc_cnt;
35 if(x == u) break;
36 }
37 }
38 }
39
40 void scc() {
41 dfs_clock = scc_cnt = 0;
42 memset(cmp,0,sizeof(cmp));
43 memset(pre,0,sizeof(pre));
44
45 for(int i = 0; i < 2 * N; ++i) if(!pre[i]) dfs(i);
46 }
47
48 void add_edge(int id,int u) {
49 int e = first[u];
50 Next[id] = e;
51 first[u] = id;
52 }
53
54 bool solve() {
55 scc();
56 for(int i = 0; i < N; ++i) {
57 if(cmp[i] == cmp[N + i]) return false;
58 }
59 return true;
60 }
61
62 void build(int a,int b,int c,char ch[],int &len) {
63 if(strcmp(ch,"AND") == 0) {
64 if(c == 0) {
65 v[len] = b;
66 add_edge(len++,a + N);
67 v[len] = a;
68 add_edge(len++,b + N);
69 } else {
70 v[len] = b + N;
71 add_edge(len++,a + N);
72 v[len] = a + N;
73 add_edge(len++,b + N);
74 v[len] = a + N;
75 add_edge(len++,a);
76 v[len] = b + N;
77 add_edge(len++,b);
78 }
79 }
80 if(strcmp(ch,"OR") == 0) {
81 if(c == 0) {
82 v[len] = b;
83 add_edge(len++,a);
84 v[len] = b;
85 add_edge(len++,b + N);
86 v[len] = a;
87 add_edge(len++,b);
88 v[len] = a;
89 add_edge(len++,a + N);
90 } else {
91 v[len] = b + N;
92 add_edge(len++,a);
93 v[len] = a + N;
94 add_edge(len++,b);
95 }
96 }
97 if(strcmp(ch,"XOR") == 0) {
98 if(c == 0) {
99 v[len] = b;
100 add_edge(len++,a);
101 v[len] = a + N;
102 add_edge(len++,b + N);
103 v[len] = a;
104 add_edge(len++,b);
105 v[len] = b + N;
106 add_edge(len++,a + N);
107 } else {
108 v[len] = b + N;
109 add_edge(len++,a);
110 v[len] = a + N;
111 add_edge(len++,b);
112 v[len] = b;
113 add_edge(len++,a + N);
114 v[len] = a;
115 add_edge(len++,b + N);
116 }
117 }
118
119 }
120
121 int main()
122 {
123 //freopen("sw.in","r",stdin);
124 scanf("%d%d",&N,&M);
125 for(int i = 0; i < 2 * N; ++i) first[i] = -1;
126 int len = 0;
127 for(int i = 1; i <= M; ++i) {
128 int a,b,c;
129 char ch[10];
130 scanf("%d%d%d%s",&a,&b,&c,ch);
131 build(a,b,c,ch,len);
132
133 }
134
135 printf("%s\n",solve() ? "YES" : "NO");
136 //cout << "Hello world!" << endl;
137 return 0;
138 }

POJ 3678,码迷,mamicode.com

时间: 2024-08-01 07:43:08

POJ 3678的相关文章

POJ 2837 Til the Cows Come Home

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 45515   Accepted: 15434 Description Bessie is out in the field and wants to get back to the barn to get as much sleep as possible before Farmer John wakes her for the morning milking. Bessi

POJ 1740 A New Stone Game(博弈)

A New Stone Game Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6586 Accepted: 3611 Description Alice and Bob decide to play a new stone game.At the beginning of the game they pick n(1<=n<=10) piles of stones in a line. Alice and Bob mov

《C和C++程序员面试秘笈[精品]》-笔记

2015-12-16 原文:在C++中可以通过域操作符"::"来直接操作全局变量 2015-12-16 原文:后缀式(i++)必须返回对象的值,所以导致在大对象的时候产生了较大的复制开销,引起效率降低.因此处理使用者自定义类型(注意不是指内建类型)的时候,应该尽可能地使用前缀式递增/递减,因为它天生"体质"较佳. 2015-12-16 原文:内建数据类型的情况,效率没有区别. 自定义数据类型的情况,++i效率较高. 2015-12-16 原文:当表达式中存在有符号类

HDU 1540 &amp;&amp; POJ 2892 Tunnel Warfare (线段树,区间合并).

~~~~ 第一次遇到线段树合并的题,又被律爷教做人.TAT. ~~~~ 线段树的题意都很好理解吧.. 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1540 http://poj.org/problem?id=2892 ~~~~ 我的代码:200ms #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #defin

POJ 1442 优先队列 模板

/* poj 1442 题意:给定M个数,每次可以插入序列一个数:再给N个数,表示在插入第几个数时输出一个数, 第一次输出序列中最小的,第二次输出序列中第二小的……以此类推,直到输出N个数. 优先队列的使用: 本题思路是建立一个小顶堆p和一个大顶堆q, q保存前k个小的数,且保证p的值都比q的大, 最后输出q的顶 */ #include <iostream> #include <cstdio> #include <algorithm> #include <queu

Poj 1830 高斯消元

开关问题 Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 5418 Accepted: 2022 Description 有N个相同的开关,每个开关都与某些开关有着联系,每当你打开或者关闭某个开关的时候,其他的与此开关相关联的开关也会相应地发生变化,即这些相联系的开关的状态如果原来为开就变为关,如果为关就变为开.你的目标是经过若干次开关操作后使得最后N个开关达到一个特定的状态.对于任意一个开关,最多只能进行一次开关操作.你的任

Poj 2796 单调栈

关于单调栈的性质,和单调队列基本相同,只不过单调栈只使用数组的尾部, 类似于栈. Accepted Code: 1 /************************************************************************* 2 > File Name: 2796.cpp 3 > Author: Stomach_ache 4 > Mail: [email protected] 5 > Created Time: 2014年07月21日 星期一

POJ - 1787 (多重背包还原路径|| 完全背包)

POJ  1787  Charlie's Change Description Charlie is a driver of Advanced Cargo Movement, Ltd. Charlie drives a lot and so he often buys coffee at coffee vending machines at motorests. Charlie hates change. That is basically the setup of your next task

poj 2386  Lake Counting DFS

n*m的矩阵W是水 .是地问有多少池塘池塘的定义是:W通过 八个 方向连接成的一片算作是一个池塘 样例输入中,有左上.左下.右侧三片连接在一起的W因而样例输出给出了3个池塘的答案 #include <cstdio> #include <iostream> #define N 110 using namespace std; int n,m; char s[N][N]; void dfs(int x,int y) { s[x][y]='.'; int i,j; for(i=-1; i