POJ - 3678 Katu Puzzle(2-SAT)

来源:互联网 发布:surface pro知乎 编辑:程序博客网 时间:2024/06/05 04:21

题目大意:给出每两个数的运算结果,问这些结果间是否存在矛盾

解题思路:直接看代码吧

#include <cstdio>#include <cstring>#include <vector>using namespace std;#define N 2010vector<int> G[N];bool mark[N];int n, m, top;int S[N];void AddEdge(int x, int valx, int y, int valy) {    x = x * 2 + valx;    y = y * 2 + valy;    G[x].push_back(y);}void init() {    for (int i = 0; i < 2 * n; i++)        G[i].clear();    int a, b, c;    char op[10];    for (int i = 0; i < m; i++) {        scanf("%d%d%d%s", &a, &b, &c, op);        if (op[0] == 'A')  {            if (c == 0) {                //a && b == 0                AddEdge(a, 1, b, 0);                AddEdge(b, 1, a, 0);            }            else {                //a && b == 1                AddEdge(a, 1, b, 1);                AddEdge(b, 1, a, 1);                AddEdge(a, 0, a, 1);                AddEdge(b, 0, b, 1);            }        }        else if(op[0] == 'O') {            if (c == 0) {                //a || b == 0                AddEdge(a, 0, b, 0);                AddEdge(b, 0, a, 0);                AddEdge(a, 1, a, 0);                AddEdge(b, 1, b ,0);            }            else {                //a || b == 1                AddEdge(a, 0, b, 1);                AddEdge(b, 0, a, 1);            }        }        else if(op[0] == 'X') {            if (c == 0) {                // a ^ b == 0                AddEdge(a, 0, b, 0);                AddEdge(a, 1, b, 1);                AddEdge(b, 0, a, 0);                AddEdge(b, 1, a, 1);            }            else {                //a ^ b == 1                AddEdge(a, 0, b, 1);                AddEdge(a, 1, b, 0);                AddEdge(b, 0, a, 1);                AddEdge(b, 1, a, 0);            }        }    }}bool dfs(int u) {    if (mark[u ^ 1])        return false;    if (mark[u])        return true;    mark[u] = true;    S[++top] = u;    for (int i = 0; i < G[u].size(); i++)        if (!dfs(G[u][i]))            return false;    return true;}void solve() {    memset(mark, 0, sizeof(mark));    for (int i = 0; i < 2 * n; i += 2) {        if (!mark[i] && !mark[i ^ 1]) {            top = 0;            if (!dfs(i)) {                while (top)                     mark[S[top--]] = false;                if (!dfs(i ^ 1)) {                    printf("NO\n");                    return ;                }            }        }    }    printf("YES\n");}int main() {    while (scanf("%d%d", &n, &m) != EOF) {        init();        solve();    }    return 0;}
0 0
原创粉丝点击