2-SAT

在这里,写了一个2-SAT的模板

#include<map>
#include<set>
#include<queue>
#include<cmath>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define  inf 0x0f0f0f0f

using namespace std;

const double pi=acos(-1.0);
const double eps=1e-8;
typedef pair<int,int>pii;
const int maxn=1000;

struct TwoSAT
{
    int n;
    vector<int> G[maxn*2];
    bool mark[maxn*2];
    int S[maxn*2],c;

    bool dfs(int x)//沿着x,向能标记的点标记,此时x为true
    {
        if (mark[x^1]) return false;//发现x的对立为true,矛盾
        if (mark[x]) return true;//在x的对立为假的情况下x为true,此时成立
        mark[x]=true;//标记x为true
        S[c++]=x;//加入S中
        for (int i=0;i<G[x].size();i++)//沿着有向边走
        if (!dfs(G[x][i])) return false;//走不通
        return true;
    }

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

    void add_clause(int x,int xval,int y,int yval)
    {
        x=x*2+xval;
        y=y*2+yval;//表示x和y有冲突
        G[x^1].push_back(y);//x的对立与y连边
        G[y^1].push_back(x);//y的对立与x连边
    }

    bool solve()
    {
        for (int i=0;i<n*2;i++)
        if (!mark[i] && !mark[i+1])//两个都不确定
        {
            c=0;
            if (!dfs(i))
            {
                while (c>0) mark[S[--c]] = false;
                if (!dfs(i+1)) return false;
            }
        }
        return true;
    }
};


int main()
{
    freopen("in.txt","r",stdin);


    fclose(stdin);
    return 0;
}

 

posted @ 2014-04-24 20:12  Hust_BaoJia  阅读(117)  评论(0编辑  收藏  举报
努力