POJ 3678 Katu Puzzle 2-sat

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

题意:给出n个数和m组数对应的位运算,判断n个数是否满足m组位运算

构图:把每个点拆成两个,一个代表0,一个代表1,总共有2*n个点,0~2*n-1

a AND b=0  2*a+1->2*b ,  2*b+1->2*a

a AND b=1  2*a->2*a+1 , 2*b->2*b+1  (AND 1 时 要求a和b同时为1,

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

其它的类似

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define Min(a,b)a<b?a:b
#define nMAX 2010
#define mMAX 2000010
int head[nMAX],sta[nMAX],dfn[nMAX],low[nMAX],belon[nMAX];
int s_edge,atype,top,times,n;
bool insta[nMAX];
struct Edge
{
    int to,next;
}edge[mMAX];

void addedge(int u,int v)
{
    s_edge++;
    edge[s_edge].to=v;
    edge[s_edge].next=head[u];
    head[u]=s_edge;
    return;
}
void tarjan(int u)
{
    dfn[u]=++times;
    low[u]=times;

    insta[u]=1;
    sta[++top]=u;
    for(int e=head[u];e;e=edge[e].next)
    {
        int v=edge[e].to;
        if(!dfn[v])
        {
            tarjan(v);
            low[u]=Min(low[u],low[v]);
        }
        else if(insta[v])
            low[u]=Min(low[u],dfn[v]);

    }
    int j;
    if(dfn[u]==low[u])
    {
        atype++;
        do
        {
            j=sta[top--];
            insta[j]=0;
            belon[j]=atype;

        }while(j!=u);
    }
    return ;
}

bool judge()
{
    for(int i=0;i<2*n;i+=2)
    {
        if(belon[i]==belon[i+1])
        return false;
    }
    return true;
}

void init()
{
    s_edge=0;
    times=0;
    top=0;
    atype=0;

    memset(head,0,sizeof(head));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(sta,0,sizeof(sta));
    memset(insta,0,sizeof(insta));
    memset(belon,0,sizeof(belon));
    return ;
}

int main()
{
    int m,i,j,k;
    char ch[5];
    while(~scanf("%d%d",&n,&m))
    {
        init();
        while(m--)
        {
           scanf("%d%d%d%s",&i,&j,&k,ch);
           if(ch[0]=='A')
           {
               if(k==0)
               {
                   addedge(2*i+1,2*j);
                   addedge(2*j+1,2*i);
               }
               else if(k==1)
               {
                   addedge(2*i,2*i+1);
                   addedge(2*j,2*j+1);
               }
           }
           if(ch[0]=='O')
           {
               if(k==0)
               {
                   addedge(2*i+1,2*i);
                   addedge(2*j+1,2*j);
               }
               else if(k==1)
               {
                   addedge(2*i,2*j+1);
                   addedge(2*j,2*i+1);
               }
           }
           if(ch[0]=='X')
           {
               if(k==0)
               {
                   addedge(2*i,2*j);
                   addedge(2*j,2*i);
                   addedge(2*i+1,2*j+1);
                   addedge(2*j+1,2*i+1);
               }
               else if(k==1)
               {
                   addedge(2*i,2*j+1);
                   addedge(2*j+1,2*i);
                   addedge(2*i+1,2*j);
                   addedge(2*j,2*i+1);
               }
           }
        }
        for(i=0;i<2*n;i++)
          if(!dfn[i])tarjan(i);
        if(judge())printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}

  

  



 







posted @ 2012-02-20 00:44  快乐.  阅读(172)  评论(0编辑  收藏  举报