2-sat [模板]

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

典型的2-sat裸题

View Code
/*====================================================*\
| 2-sat问题:判断某个数的0或1的取值是否存在满足条件的解
\*====================================================*/
const int MM = 222222;
int N, M;
bool inq[MM];
int cur,cnt,belong[MM];
int stack[MM], top,dfn[MM], low[MM];
int head[MM], NE;
vector<int>edge[MM];

/*====================================================*\
| a  AND  b = 1       <==>  _a->a  _b->b
| a  AND  b = 0       <==>  a->_b  b->_a
| a  OR  b = 1        <==>  _a->b  _b->a
| a  OR  b = 0        <==>  a->_a  b->_b
| a  XOR b = 1        <==>  _a->b  a->_b  _b->a  b->_a
| a  XOR b = 0        <==>  a->b  _a->_b  b->a  _b->_a
| a表示a点选1,_a表示a点选0。
\*====================================================*/
void get_data() {
     int i,j,k,a,b,c; char ch[10];
     for(i=0;i<M;i++) {
          scanf("%d%d%d%s",&a,&b,&c,ch);
          a<<=1; b<<=1;
          if(ch[0]=='A') {
              if(c) { edge[a^1].push_back(a); edge[b^1].push_back(b); }
              else    { edge[a].push_back(b^1); edge[b].push_back(a^1); }
          }
          if(ch[0]=='O') {
              if(c) { edge[a^1].push_back(b);edge[b^1].push_back(a); }
              else    {edge[a].push_back(a^1); edge[b].push_back(b^1); }
          }    
          if(ch[0]=='X') {
              if(c) { edge[a^1].push_back(b); edge[a].push_back(b^1); edge[b^1].push_back(a); edge[b].push_back(a^1); }
              else { edge[a].push_back(b); edge[a^1].push_back(b^1); edge[b].push_back(a); edge[b^1].push_back(a^1); }
          }
     }
}

void tarjan(int u) {
     int i,j,k,v;
     low[u]=dfn[u]=++cnt;
     stack[top++]=u;
     inq[u]=true;
     for(i=0;i<edge[u].size();i++) {
         v=edge[u][i];
         if(!dfn[v]) {
             tarjan(v);
             low[u]=f_min(low[u],low[v]);
         }
         if(inq[v]) low[u]=f_min(low[u],dfn[v]);
     }
     if(dfn[u]==low[u]) {
            cur++;
            do {
                v=stack[--top];
                belong[v]=cur;
                inq[v]=false;
            }while(u!=v);
     }
}

bool ok() {
     int i,j,k;
     memset(dfn,0,sizeof(dfn));
     cnt=top=cur=0;
     for(i=0;i<(N<<1);i++) {
         if(!dfn[i])  tarjan(i);
     }
     for(i=0;i<(N<<1);i+=2) {
         if(belong[i]==belong[i^1]) return false;
     }
     return true;
}

void solve() {
     int i,j,k;
     if(!ok())  puts("NO");
     else puts("YES");
}

 

posted @ 2013-05-07 21:22  zhang1107  阅读(118)  评论(0编辑  收藏  举报