zoukankan      html  css  js  c++  java
  • poj 3678 Katu Puzzle 2-SAT

    Katu Puzzle
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 6702   Accepted: 2463

    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.
    ------------

    真正理解了2-SAT才能建出图

    ------------

    /** head-file **/
    
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <iomanip>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <list>
    #include <set>
    #include <map>
    #include <algorithm>
    
    /** define-for **/
    
    #define REP(i, n) for (int i=0;i<int(n);++i)
    #define FOR(i, a, b) for (int i=int(a);i<int(b);++i)
    #define DWN(i, b, a) for (int i=int(b-1);i>=int(a);--i)
    #define REP_1(i, n) for (int i=1;i<=int(n);++i)
    #define FOR_1(i, a, b) for (int i=int(a);i<=int(b);++i)
    #define DWN_1(i, b, a) for (int i=int(b);i>=int(a);--i)
    #define REP_N(i, n) for (i=0;i<int(n);++i)
    #define FOR_N(i, a, b) for (i=int(a);i<int(b);++i)
    #define DWN_N(i, b, a) for (i=int(b-1);i>=int(a);--i)
    #define REP_1_N(i, n) for (i=1;i<=int(n);++i)
    #define FOR_1_N(i, a, b) for (i=int(a);i<=int(b);++i)
    #define DWN_1_N(i, b, a) for (i=int(b);i>=int(a);--i)
    
    /** define-useful **/
    
    #define clr(x,a) memset(x,a,sizeof(x))
    #define sz(x) int(x.size())
    #define see(x) cerr<<#x<<" "<<x<<endl
    #define se(x) cerr<<" "<<x
    #define pb push_back
    #define mp make_pair
    
    /** test **/
    
    #define Display(A, n, m) {                      
        REP(i, n){                                  
            REP(j, m) cout << A[i][j] << " ";       
            cout << endl;                           
        }                                           
    }
    
    #define Display_1(A, n, m) {                    
        REP_1(i, n){                                
            REP_1(j, m) cout << A[i][j] << " ";     
            cout << endl;                           
        }                                           
    }
    
    using namespace std;
    
    /** typedef **/
    
    typedef long long LL;
    
    /** Add - On **/
    
    const int direct4[4][2]={ {0,1},{1,0},{0,-1},{-1,0} };
    const int direct8[8][2]={ {0,1},{1,0},{0,-1},{-1,0},{1,1},{1,-1},{-1,1},{-1,-1} };
    const int direct3[6][3]={ {1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1} };
    
    const int MOD = 1000000007;
    const int INF = 0x3f3f3f3f;
    const long long INFF = 1LL << 60;
    const double EPS = 1e-9;
    const double OO = 1e15;
    const double PI = acos(-1.0); //M_PI;
    
    const int maxn=11111;
    const int maxm=2111111;
    int n,m;
    struct EDGENODE{
        int to;
        int next;
    };
    struct TWO_SAT{
        int head[maxn*2];
        EDGENODE edges[maxm*2];
        int edge;
        int n;
        void init(int n){
            this->n=2*n;
            clr(head,-1);
            edge=0;
        }
        void addedge(int u,int v){
            edges[edge].to=v,edges[edge].next=head[u],head[u]=edge++;
        }
        // x = xval or y = yval
        //!x->y,!y->x
        void add_clause(int x,int xval,int y,int yval){
            x=x*2+xval;
            y=y*2+yval;
            addedge(x^1,y);
            addedge(y^1,x);
        }
        //x=xval
        //!x=x
        void add_con(int x,int xval){
            x=x*2+xval;
            addedge(x^1,x);
        }
        //--
        void add_self(int x,int xval,int y,int yval){
            x=x*2+xval;
            y=y*2+yval;
            addedge(x,y);
        }
        int pre[maxn],lowlink[maxn],sccno[maxn],scc_cnt,dfs_clock;
        stack<int>stk;
        void dfs(int u)
        {
            pre[u]=lowlink[u]=++dfs_clock;
            stk.push(u);
            for (int i=head[u];i!=-1;i=edges[i].next){
                int v=edges[i].to;
                if (!pre[v]){
                    dfs(v);
                    lowlink[u]=min(lowlink[u],lowlink[v]);
                } else if (!sccno[v]){
                    lowlink[u]=min(lowlink[u],pre[v]);
                }
            }
            if (lowlink[u]==pre[u]){
                scc_cnt++;
                int x;
                do{
                    x=stk.top();
                    stk.pop();
                    sccno[x]=scc_cnt;
                }while (x!=u);
            }
        }
        void find_scc(int n)
        {
            dfs_clock=scc_cnt=0;
            clr(sccno,0);
            clr(pre,0);
            while (!stk.empty()) stk.pop();
            REP(i,n) if (!pre[i]) dfs(i);
        }
        bool solve(){
            find_scc(n);
            for (int i=0;i<n;i+=2){
                if (sccno[i]==sccno[i^1]) return false;
            }
            return true;
        }
    }TwoSAT;
    
    int main()
    {
        int a,b,c;
        char s[4];
        while (~scanf("%d%d",&n,&m))
        {
            TwoSAT.init(n);
            REP(i,m)
            {
                scanf("%d%d%d%s",&a,&b,&c,s);
                /*
                if (!strcmp(s,"AND")){
                    if (c==1){
                        TwoSAT.add_self(a,1,a,0);
                        TwoSAT.add_self(b,1,b,0);
                    }else if (c==0){
                        TwoSAT.add_self(a,0,b,1);
                        TwoSAT.add_self(b,0,a,1);
                    }
                }
                if (!strcmp(s,"OR")){
                    if (c==1){
                        TwoSAT.add_self(a,1,b,0);
                        TwoSAT.add_self(b,1,a,0);
                    }else if (c==0){
                        TwoSAT.add_self(a,0,a,1);
                        TwoSAT.add_self(b,0,b,1);
                    }
                }
                if (!strcmp(s,"XOR")){
                    if (c==1){
                        TwoSAT.add_self(a,0,b,1);
                        TwoSAT.add_self(b,0,a,1);
                        TwoSAT.add_self(a,1,b,0);
                        TwoSAT.add_self(b,1,a,0);
                    }else if (c==0){
                        TwoSAT.add_self(a,0,b,0);
                        TwoSAT.add_self(b,0,a,0);
                        TwoSAT.add_self(a,1,b,1);
                        TwoSAT.add_self(b,1,a,1);
                    }
                }*/
                if (!strcmp(s,"AND")){
                    if (c==1){
                        TwoSAT.add_con(a,1);
                        TwoSAT.add_con(b,1);
                    }else if (c==0){
                        TwoSAT.add_clause(a,0,b,0);
                    }
                }
                if (!strcmp(s,"OR")){
                    if (c==1){
                        TwoSAT.add_clause(a,1,b,1);
                    }else if (c==0){
                        TwoSAT.add_con(a,0);
                        TwoSAT.add_con(b,0);
                    }
                }
                if (!strcmp(s,"XOR")){
                    if (c==1){
                        TwoSAT.add_clause(a,1,b,1);
                        TwoSAT.add_clause(a,0,b,0);
                    }else if (c==0){
                        TwoSAT.add_clause(a,1,b,0);
                        TwoSAT.add_clause(a,0,b,1);
                    }
                }
            }
            if (TwoSAT.solve()) puts("YES");
            else puts("NO");
        }
        return 0;
    }
    




  • 相关阅读:
    2013 年最不可思议的 10 个硬件开源项目
    三款SDR平台对比:HackRF,bladeRF和USRP
    形同虚设:花费700美元便可突破门禁
    oracle timestamp和date区别
    linux服务器性能——CPU、内存、流量、磁盘使用率的监控
    通过安装memadmin对memcache进行可视化管理
    SNMP MIBs and IPv6
    使用 cacti 监控 windows 服务器硬盘的 I/O 状况
    snmp对超过16T的磁盘大小识别不对的解决办法
    源码编译安装net-snmp
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681601.html
Copyright © 2011-2022 走看看