zoukankan      html  css  js  c++  java
  • 2-sat(and,or,xor)poj3678

    Katu Puzzle
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 7949   Accepted: 2914

    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 Via 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
    题意:给出一个连通图对于每条边都有一种操作(and,or,xor),使两个端点的操作结果是c,问是否存在这样一个连通图,存在输出YES否者输出NO
    分析:裸的2-sat操作
    公式:i&j=1 (i-->i+n) (j-->j+n)
    i&j=0 (i+n-->j) (j+n-->i)
    i|j=1 (i-->j+n) (j-->i+n)
    i|j=0 (i+n-->i) (j+n-->j)
    i^j=1 (i-->j+n) (j+n-->i) (j-->i+n) (i+n-->j)
    i^j=0 (i-->j) (j-->i) (i+n-->j+n) (j+n-->i+n)
    程序;
    #include"string.h"
    #include"stdio.h"
    #include"iostream"
    #include"algorithm"
    #include"queue"
    #include"stack"
    #include"stdlib.h"
    #include"math.h"
    #define inf 10000000
    #define INF 0x3f3f3f3f
    const double PI=acos(-1.0);
    const double r2=sqrt(2.0);
    const int M=1010;
    const int N=1010*1000*4;
    #define eps 1e-10
    using namespace std;
    struct node
    {
        int u,v,next;
    }edge[N];
    stack<int>q;
    int t,head[M],dfn[M],low[M],belong[M],use[M],num,index;
    void init()
    {
        t=0;
        memset(head,-1,sizeof(head));
    }
    void add(int u,int v)
    {
        edge[t].u=u;
        edge[t].v=v;
        edge[t].next=head[u];
        head[u]=t++;
    }
    void tarjan(int u)
    {
        dfn[u]=low[u]=++index;
        q.push(u);
        use[u]=1;
        for(int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].v;
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(use[v])
                low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u])
        {
            num++;
            int p;
            do
            {
                p=q.top();
                q.pop();
                use[p]=0;
                belong[p]=num;
            }while(p!=u);
        }
    }
    int slove(int n)
    {
        num=index=0;
        memset(use,0,sizeof(use));
        memset(dfn,0,sizeof(dfn));
        for(int i=0;i<n*2;i++)
            if(!dfn[i])
            tarjan(i);
        for(int i=0;i<n;i++)
            if(belong[i]==belong[i+n])
            return 0;
        return 1;
    }
    int main()
    {
        int n,m,a,b,c,i;
        char str[9];
        while(scanf("%d%d",&n,&m)!=-1)
        {
            init();
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d%s",&a,&b,&c,str);
                if(strcmp(str,"AND")==0)
                {
                    if(c)
                    {
                        add(a,a+n);
                        add(b,b+n);
                    }
                    else
                    {
                        add(b+n,a);
                        add(a+n,b);
                    }
                }
                else if(strcmp(str,"OR")==0)
                {
                    if(c)
                    {
                        add(b,a+n);
                        add(a,b+n);
                    }
                    else
                    {
                        add(a+n,a);
                        add(b+n,b);
                    }
                }
                else
                {
                    if(c)
                    {
                        add(a,b+n);
                        add(b,a+n);
                        add(b+n,a);
                        add(a+n,b);
                    }
                    else
                    {
                        add(a,b);
                        add(b,a);
                        add(a+n,b+n);
                        add(b+n,a+n);
                    }
                }
            }
            if(slove(n))
                printf("YES
    ");
            else
                printf("NO
    ");
        }
    }
    



  • 相关阅读:
    How to create jar for Android Library Project
    Very large tabs in eclipse panes on Ubuntu
    64bit Ubuntu, Android AAPT, R.java
    Linux(Ubuntu)下如何安装JDK
    Configure xterm Fonts and Colors for Your Eyeball
    建立、配置和使用Activity——启动其他Activity并返回结果
    建立、配置和使用Activity——使用Bundle在Activity之间交换数据
    建立、配置和使用Activity——启动、关闭Activity
    建立、配置和使用Activity——Activity
    异步任务(AsyncTask)
  • 原文地址:https://www.cnblogs.com/mypsq/p/4348123.html
Copyright © 2011-2022 走看看