• 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
    ");
        }
    }
    



  • 相关阅读:
    关于如何绑定Jquery 的scroll事件(兼容浏览器 Wookmark瀑布流插件)
    HttpHelper类使用方法
    Jquery实现弹出选择框选择后返回,支持多级分类
    让asp.net网站支持多语言,使用资源文件
    关于Android SDK Manager无法获取更新列表的正确设置
    Eclipse使用技巧总结
    配置java环境变量
    sqlserver游标使用和循环
    压缩SQLServer数据库日志的一个存储过程
    Jquery EasyUI封装简化操作
  • 原文地址:https://www.cnblogs.com/mypsq/p/4348123.html
Copyright © 2020-2023  润新知