zoukankan      html  css  js  c++  java
  • POJ 3678 Katu Puzzle

    Katu Puzzle

    链接

    题意:

      有n个变量(每个变量只能是0或者1),m个等式,每个等式形如$x_i op x_j = c, op in["and","or","xor"],c in [0,1]$,问能否给n个变量赋值,满足所有等式。

    分析:

      2-sat问题。

      注意一下a&b=1的时候,要求a,b都为1,那么就是说明“如果a为0,那么a为1”,所以连边a->a+n。

    代码:

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 2005;
    struct Edge{ int to, nxt; } e[2000005];
    int head[N], dfn[N], low[N], sk[N], bel[N], En, Index, top, tot;
    bool vis[N];
    
    inline void add(int u,int v) {
        ++En; e[En].to = v, e[En].nxt = head[u]; head[u] = En;
    }
    void tarjan(int u) {
        dfn[u] = low[u] = ++Index;
        sk[++top] = u, vis[u] = 1;
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (!dfn[v]) {
                tarjan(v);
                low[u] = min(low[u], low[v]);
            }
            else if (vis[v]) low[u] = min(low[u], dfn[v]);
        }
        if (low[u] == dfn[u]) {
            ++tot;
            do {
                vis[sk[top]] = 0;
                bel[sk[top]] = tot;
                top --;
            } while (sk[top + 1] != u);
        }
    }
    int main() {
    //    freopen("1.txt", "r", stdin);
        int n = read(), m = read();
        char op[10];
        for (int i = 1; i <= m; ++i) {
            int a = read(), b = read(), c = read();scanf("%s",op);
            a ++, b ++;
            if (op[0] == 'A')  {
                if (c == 0) add(a + n, b), add(b + n, a);
                else add(a, a + n), add(b, b + n);
            }
            else if (op[0] == 'O') {
                if (c == 0) add(a + n, a), add(b + n, b);
                else add(a, b + n), add(b, a + n);
            }
            else if (op[0] == 'X') {
                if (c == 0) add(a, b), add(b + n, a + n), add(b, a), add(a + n, b + n);
                else add(a, b + n), add(b, a + n), add(b + n, a), add(a + n, b);
            }
        }
        for (int i = 1; i <= n + n; ++i) if (!dfn[i]) tarjan(i);
        for (int i = 1; i <= n; ++i) {
            if (bel[i] == bel[i + n]) { puts("NO"); return 0; }
        }
        puts("YES");
        return 0;
    }
  • 相关阅读:
    ThinkPHP实现定时任务
    VUE 父子组件之间通信传值 props和 $emit,事件触发传值ref,以及兄弟组件之间的通信传值 eventBus
    JS链接转换为二维码
    VUE 动态切换列表active样式
    微信内置浏览器video标签自动全屏的问题
    JS监听video视频播放时间
    JS数据统计表 highcharts.js的运用
    JS 自动返回每个月的天数
    JS 一键复制插件应用 和 原生实现
    JS enter键一键登录
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10289270.html
Copyright © 2011-2022 走看看