zoukankan      html  css  js  c++  java
  • POJ3678Katu Puzzle(2sat)

    POJ 2-sat 六题第二题

    http://blog.sina.com.cn/s/blog_64675f540100k15b.html

    题目描述:

    一些点,点的取值可以是0或者1,没有告诉你具体取值。

    一些边,有权值,有运算方式(并,或,异或),要求和这条边相连的两个点经过边上的运算后的结果是边的权值。

    问你有没有可能把每个点赋值满足所有边的要求。

    解题报告:

    每个点只有0,1两种值,并且和边对面的点有约束条件,所以可以转化为2-sat问题。

    令i表示点i去0,i + n表示点i取1.

    点i与点j and 等于0时。 i + n -> j, j + n -> i

    and 等于 1时,要求i和j必须为1,不能为0.

    不能为0的处理时:如果i取0,那么i就要取1.

    即:i -> i + n。

    剩下的就是类似的方法了

    // File Name: 3678.cpp
    // Author: zlbing
    // Created Time: 2013/1/22 23:13:52
    
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cstdlib>
    #include<cstdio>
    #include<set>
    #include<map>
    #include<vector>
    #include<cstring>
    #include<stack>
    using namespace std;
    #define MAXN 1000+50
    struct TwoSAT{
        int n;
        vector<int>G[MAXN*2];
        bool mark[MAXN*2];
        stack<int>S;
        bool dfs(int x)
        {
            if(mark[x^1])return false;
            if(mark[x])return true;
            mark[x]=true;
            S.push(x);
            for(int i=0;i<G[x].size();i++)
            {
                int v=G[x][i];
                if(!dfs(v))return false;
            }
            return true;
        }
        void init(int _n)
        {
            n=_n;
            for(int i=0;i<2*n;i++)
                G[i].clear();
            memset(mark,0,sizeof(mark));
        }
        void add_clause(int x,int y)
        {
            G[x].push_back(y);
        }
        bool solve()
        {
            for(int i=0;i<2*n;i=i+2)
            {
                if(!mark[i]&&!mark[i+1]){
                      while(!S.empty())
                      {
                          S.pop();
                      }
                    if(!dfs(i))
                    {
                        while(!S.empty())
                        {
                            mark[S.top()]=false;
                            S.pop();
                        }
                        if(!dfs(i+1))return false;
                    }
                }
            }
            
    //        for(int i=0;i<2*n;i++)
    //            if(mark[i])printf("%d ",T[i/2][i%2]);
    //        printf("\n");
            return true;
        }
    };
    
    int main(){
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            TwoSAT solver;
            solver.init(n);
                int a,b,c;
                char ch[10];
            for(int i=0;i<m;i++)
            {
                scanf("%d%d%d",&a,&b,&c);
                scanf("%s",ch);
                if(c)
                {
                    if(ch[0]=='A')
                    {
                        solver.add_clause(2*a,2*a+1);
                        solver.add_clause(2*b,2*b+1);
                    }
                    if(ch[0]=='O')
                    {
                        solver.add_clause(2*a,2*b+1);
                        solver.add_clause(2*b,2*a+1);
                    }
                    if(ch[0]=='X')
                    {
                        solver.add_clause(2*a,2*b+1);
                        solver.add_clause(2*a+1,2*b);
                        solver.add_clause(2*b,2*a+1);
                        solver.add_clause(2*b+1,2*a);
                    }
                }
                else
                {
                    if(ch[0]=='A')
                    {
                        solver.add_clause(2*a+1,2*b);
                        solver.add_clause(2*b+1,2*a);
                    }
                    if(ch[0]=='O')
                    {
                        solver.add_clause(2*a+1,2*a);
                        solver.add_clause(2*b+1,2*b);
                    }
                    if(ch[0]=='X')
                    {
                        solver.add_clause(2*a,2*b);
                        solver.add_clause(2*a+1,2*b+1);
                        solver.add_clause(2*b,2*a);
                        solver.add_clause(2*b+1,2*a+1);
                    }
                }
            }
            if(solver.solve())
                printf("YES\n");
            else printf("NO\n");
        }
        return 0;
    }
  • 相关阅读:
    小程序登录及用户信息和手机号的获取
    Node.js 获取微信JS-SDK CONFIG
    代码顺序的重要性
    七牛视频防盗链处理
    《码农翻身》读书笔记
    白夜行
    看见
    用node.js写一个jenkins发版脚本
    Node.js 使用 RSA 做加密
    七牛视频切片方案
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2882258.html
Copyright © 2011-2022 走看看