POJ 3905 Perfect Election(简单2-SAT)

来源:互联网 发布:丹江口水电站待遇 知乎 编辑:程序博客网 时间:2024/05/21 15:01

POJ 3905 Perfect Election(简单2-SAT)

http://poj.org/problem?id=3905

题意:

        这里有1到N个人正在进行议员选举,每个人有2种结果,选上(0),未选上(1).现在的问题是,有M个选民的议员,结果必须符合这M条意愿,问你是否存在这种选举结果.

分析:

        由于每条意愿都是或的关系.则直接用2-sat添加对应边即可.

        简单2-SAT问题,注意把候选人序号改成0到N-1即可.

AC代码:

#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespace std;const int maxn = 1000+10;struct TwoSAT{    int n;    vector<int> G[maxn*2];    int S[maxn*2],c;    bool mark[maxn*2];    bool dfs(int x)    {        if(mark[x^1]) return false;        if(mark[x]) return true;        mark[x]= true;        S[c++]=x;        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;        G[x^1].push_back(y);        G[y^1].push_back(x);    }    bool solve()    {        for(int i=0;i<2*n;i+=2)        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;    }}TS;int main(){    int n,m;    while(scanf("%d%d",&n,&m)==2)    {        TS.init(n);        for(int i=0;i<m;i++)        {            int a,b;            scanf("%d%d",&a,&b);            TS.add_clause(abs(a)-1,a<0?1:0,abs(b)-1,b<0?1:0); //记得abs(a)-1        }        printf("%d\n",TS.solve()?1:0);    }    return 0;}


0 0
原创粉丝点击