poj 3678 Katu Puzzle(Two Sat)

题目链接:http://poj.org/problem?id=3678

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;

const int maxn = 1050;

struct Two_Sat
{
    int n;
    vector<int> G[maxn*2];
    bool mark[maxn*2];
    int s[maxn*2],cnt;

    void init(int n)
    {
        this->n = n;
        memset(mark,0,sizeof(mark));
        for(int i=0; i<n*2; i++) G[i].clear();
    }

    void add_clause(int u,int v,int flag,char symbol)
    {
        u = u*2 + flag;
        v = v*2 + flag;
        if(symbol == 'A')
        {
            if(flag)
            {
                G[u].push_back(v);
                G[v].push_back(u);
                G[u^1].push_back(u);
                G[v^1].push_back(v);
            }
            else
            {
                G[u^1].push_back(v);
                G[v^1].push_back(u);
            }
        }
        else if(symbol == 'O')
        {
            if(flag)
            {
                G[u^1].push_back(v);
                G[v^1].push_back(u);
            }
            else
            {
                G[u].push_back(v);
                G[v].push_back(u);
                G[u^1].push_back(u);
                G[v^1].push_back(v);
            }
        }
        else
        {
            if(flag)
            {
                G[u^1].push_back(v);
                G[v].push_back(u^1);
                G[v^1].push_back(u);
                G[u].push_back(v^1);
            }
            else
            {
                G[u].push_back(v);
                G[v].push_back(u);
                G[u^1].push_back(v^1);
                G[v^1].push_back(u^1);
            }
        }
    }

    bool dfs(int u)
    {
        if(mark[u^1])   return false;
        if(mark[u])     return true;
        mark[u] = true;
        s[cnt++] = u;
        for(int i=0; i<G[u].size(); i++)
        {
            if(!dfs(G[u][i])) return false;
        }
        return true;
    }

    bool solve()
    {
        for(int i=0; i<n*2; i+=2)
        {
            if(!mark[i] && !mark[i+1])
            {
                cnt = 0;
                if(!dfs(i))
                {
                    while(cnt>0) mark[s[--cnt]] = false;
                    if(!dfs(i+1))   return false;
                }
            }
        }
        return true;
    }
}solver;


int main()
{
    //freopen("E:\acm\input.txt","r",stdin);
    int N,M;
    while(cin>>N>>M)
    {
        solver.init(N);
        for(int i=1; i<=M; i++)
        {
            int a,b,c;
            char s[5];
            scanf("%d %d %d %s",&a,&b,&c,s);
            solver.add_clause(a,b,c,s[0]);
        }
        if(solver.solve())  printf("YES
");
        else                printf("NO
");
    }
}
View Code
原文地址:https://www.cnblogs.com/acmdeweilai/p/3348308.html