POJ 3678 Katu Puzzle(2-sat)

来源:互联网 发布:数据库如何优化 编辑:程序博客网 时间:2024/04/27 16:09

POJ 3678 Katu Puzzle

题目链接

题意:就根据那几个表达式,推算有没可能构造出解

思路:基本的2-sat,把表达式都转化成2-sat的形式即可

代码:

#include <cstdio>#include <cstring>#include <cstdlib>#include <vector>#include <algorithm>using namespace std;const int MAXNODE = 2005;struct TwoSet {int n;vector<int> g[MAXNODE * 2];bool mark[MAXNODE * 2];int S[MAXNODE * 2], sn;void init(int tot) {n = tot * 2;for (int i = 0; i < n; i += 2) {g[i].clear();g[i^1].clear();}memset(mark, false, sizeof(mark));}void add_Edge(int u, int uval, int v, int vval) {u = u * 2 + uval;v = v * 2 + vval;g[u^1].push_back(v);g[v^1].push_back(u);}bool dfs(int u) {if (mark[u^1]) return false;if (mark[u]) return true;mark[u] = true;S[sn++] = u;for (int i = 0; i < g[u].size(); i++) {int v = g[u][i];if (!dfs(v)) return false;}return true;}bool solve() {for (int i = 0; i < n; i += 2) {if (!mark[i] && !mark[i + 1]) {sn = 0;if (!dfs(i)) {for (int j = 0; j < sn; j++)mark[S[j]] = false;sn = 0;if (!dfs(i + 1)) return false;}}}return true;}} gao;int n, m;int a, b, c;char op[10];int main() {while (~scanf("%d%d", &n, &m)) {gao.init(n);while (m--) {scanf("%d%d%d%s", &a, &b, &c, op);if (op[0] == 'A') {if (c == 1) {gao.add_Edge(a, 1, a, 1);gao.add_Edge(b, 1, b, 1);} else gao.add_Edge(a, 0, b, 0);}if (op[0] == 'O') {if (c == 0) {gao.add_Edge(a, 0, a, 0);gao.add_Edge(b, 0, b, 0);} else gao.add_Edge(a, 1, b, 1);}if (op[0] == 'X') {if (c == 1) {gao.add_Edge(a, 0, b, 0);gao.add_Edge(a, 1, b, 1);}else {gao.add_Edge(a, 0, b, 1);gao.add_Edge(a, 1, b, 0);}}}printf("%s\n", gao.solve() ? "YES" : "NO");}return 0;}


1 0
原创粉丝点击