• POJ 3678--Katu Puzzle(2-SAT)


    感觉这题比较裸,表现出了2-sat的本质。

    不过构图我想的还是太简单了,a&b=1我只连了 a1->b1,b1->a1,但其实是不对的。这样连,a0和b0可以同时选到。应该连a0->a1,b0->b1这样就能保证a0,b0都不被选到。或运算同理。

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <bitset>
    #include <cstdio>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <list>
    #include <map>
    #include <set>
    #define pk(x) printf("%d ", x)
    using namespace std;
    #define PI acos(-1.0)
    #define EPS 1E-6
    #define clr(x,c) memset(x,c,sizeof(x))
    //#pragma comment(linker, "/STACK:102400000,102400000")
    typedef long long ll;

    const int N = 1010;
    const int M = 2000020;

    struct Edge {
        int from, to, next;
    } edge[M], edge2[M];
    int head[N];
    int cntE;
    void addedge(int u, int v) {
        edge[cntE].from = u; edge[cntE].to = v; edge[cntE].next = head[u]; head[u] = cntE++;
    }

    int dfn[N], low[N], idx;
    int stk[N], top;
    int in[N];
    int kind[N], cnt;

    void tarjan(int u)
    {
        dfn[u] = low[u] = ++idx;
        in[u] = true;
        stk[++top] = u;
        for (int i = head[u]; i != -1; i = edge[i].next) {
            int v = edge[i].to;
            if (!dfn[v]) tarjan(v), low[u] = min(low[u], low[v]);
            else if (in[v]) low[u] = min(low[u], dfn[v]);
        }
        if (low[u] == dfn[u]) {
            ++cnt;
            while (1) {
                int v = stk[top--]; kind[v] = cnt; in[v] = false;
                if (v == u) break;
            }
        }
    }

    bool sat(int n) // 序号从0开始
    {
        for (int i = 0; i < n; ++i) if (!dfn[i]) tarjan(i);
        for (int i = 0; i < n; i += 2) {
            if (kind[i] == kind[i+n]) return false;
        }
        return true;
    }

    void init() {
        memset(head, -1, sizeof head);
        memset(dfn, 0, sizeof dfn);
        memset(in, false, sizeof in);
        cntE = idx = top = cnt = 0;
    }

    int main()
    {
        int n, m;
        int a, b, c;
        char op[10];
        while (~scanf("%d%d", &n, &m)) {
            init();
            while (m--) {
                scanf("%d%d%d%s", &a, &b, &c, op); // 0 1
                if (*op == 'A') {//and
                    if (c == 1) {
                        addedge(a, a+n);
                        addedge(b, b+n);
                    } else {
                        addedge(a+n, b);
                        addedge(b+n, a);
                    }
                } else if (*op == 'X') {//xor
                    if (c == 1) { //1^0=1;
                        addedge(a+n, b);
                        addedge(b+n, a);
                        addedge(a, b+n);
                        addedge(b, a+n);
                    } else {
                        addedge(a+n, b+n);
                        addedge(b+n, a+n);
                        addedge(a, b);
                        addedge(b, a);
                    }
                } else {//or 0|0=0
                    if (c == 1) {
                        addedge(a, b+n);
                        addedge(b, a+n);
                    } else {
                        addedge(a+n, a);
                        addedge(b+n, b);
                    }
                }
            }
            if (sat(n)) puts("YES");
            else puts("NO");
        }
        return 0;
    }
  • 相关阅读:
    Orcale分析函数OVER(PARTITION BY... ORDER BY...)的讲解
    Linux下安装Redmine(项目管理软件)
    CentOS5.4安装redmine详细步骤
    CentOS安装redmine 2后的简单配置
    在linux上安装redmine
    Linux安装MediaWiki
    Linux下安装配置MediaWiKi全过程
    用Navicat_SSH 连接数据库服务器
    基于C#的MongoDB数据库开发应用(4)--Redis的安装及使用
    基于C#的MongoDB数据库开发应用(3)--MongoDB数据库的C#开发之异步接口
  • 原文地址:https://www.cnblogs.com/wenruo/p/5886277.html
Copyright © 2020-2023  润新知