zoukankan      html  css  js  c++  java
  • poj3678 Katu Puzzle

    Katu Puzzle
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 10239   Accepted: 3823

    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

    分析:每个数可以取0也可以取1,那么就是2-SAT问题!2-SAT问题最重要的就是建边,建边的关键是“必须”,也就是说,当a时,必须b,才从a连边到b,这道题涉及到自己到自己的反节点的连边,具体看代码:
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <stack>
    
    using namespace std;
    
    const int maxn = 1010 * 3,maxm = 2000010;
    
    int n,m,head[maxn],top,to[maxm],nextt[maxm],tot = 1,dfs_clock,pre[maxn],low[maxn],scc[maxn];
    
    stack <int> s;
    
    void add(int x,int y)
    {
        to[tot] = y;
        nextt[tot] = head[x];
        head[x] = tot++;    
    } 
    
    void tarjan(int u)
    {
        pre[u] = low[u] = ++dfs_clock;
        s.push(u);
        for (int i = head[u];i; i = nextt[i])
        {
            int v = to[i];
            if (!pre[v])
            {
                tarjan(v);
                low[u] = min(low[u],low[v]);
            }
            else
            if (!scc[v])
            low[u] = min(low[u],pre[v]);
        }
        if (pre[u] == low[u])
        {
            top++;
            while (1)
            {
                int t = s.top();
                s.pop();
                scc[t] = top;
                if (t == u)
                break;
            }
        }
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i = 1; i <= m; i++)
        {
            int a,b,c;
            char op[5];
            scanf("%d%d%d",&a,&b,&c);
            scanf("%s",op);
            if (op[0] == 'A') //and
            {
                if (c == 1)
                {
                    add(a + n,b + n);
                    add(b + n,a + n);
                    add(a,a + n); //a如果为0显然不能满足要求,所以a必须为1,所以从0连向1
                    add(b,b + n);
                }
                else
                {
                    add(a + n,b);
                    add(b + n,a);
                }
            }
            if (op[0] == 'X')
            {
                if (c == 1)
                {
                    add(a,b + n);
                    add(a + n,b);
                    add(b, a + n);
                    add(b + n,a);
                }
                else
                {
                    add(a,b);
                    add(b,a);
                    add(a + n,b + n);
                    add(b + n,a + n);
                }
            }
            if (op[0] == 'O')
            {
                if (c == 1)
                {
                    add(a,b + n);
                    add(b,a + n);
                }
                else
                {
                    add(a,b);
                    add(b,a);
                    add(a + n,a); //a,b必须全都为0才可以,选1后我们强行让它选0.
                    add(b + n,b);
                }
            }
        }
        for (int i = 0; i <= 2 * n - 1; i++)
        if (!pre[i])
        tarjan(i);
        for (int i = 0; i < n; i++)
        if (scc[i] == scc[i + n])
        {
            printf("NO
    ");
            return 0;
        } 
        printf("YES
    ");
         
        return 0;
    }
  • 相关阅读:
    用msi安装MySQL时MySQL Server组件不能安装,或安装失败
    在Django中连接MySQL数据库(Python3)
    2,简单的Python爬虫
    把自己的电脑做成服务器,并搭建自己的网站
    任务计划程序(让计算机自动执行程序)
    1,Python爬虫环境的安装
    response和request的区别以及常见问题解决
    Microsoft Visual Studio 2010 Service Pack 1 更新 (KB3002340)
    设置radiobutton 都不选中
    QQ邮件发送问题
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7527076.html
Copyright © 2011-2022 走看看