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;
    }
  • 相关阅读:
    Linux内核网络协议栈优化总纲
    Java实现 蓝桥杯VIP 算法训练 连续正整数的和
    Java实现 蓝桥杯VIP 算法训练 连续正整数的和
    Java实现 蓝桥杯VIP 算法训练 寂寞的数
    Java实现 蓝桥杯VIP 算法训练 寂寞的数
    Java实现 蓝桥杯VIP 算法训练 学做菜
    Java实现 蓝桥杯VIP 算法训练 学做菜
    Java实现 蓝桥杯VIP 算法训练 判断字符位置
    Java实现 蓝桥杯VIP 算法训练 判断字符位置
    Java实现 蓝桥杯VIP 算法训练 链表数据求和操作
  • 原文地址:https://www.cnblogs.com/arbitrary/p/2882258.html
Copyright © 2011-2022 走看看