zoukankan      html  css  js  c++  java
  • 2sat [模板]

    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");
    }
  • 相关阅读:
    什么是主从复制、读写分离、为什么要使用
    Swift 4.0 + Ipad开发项目中值得注意知识点
    Swift细节记录<一>
    ECMAScript 6复习<一>
    Swift4.0复习访问控制与作用域
    Swift4.0复习操作符方法与操作符的定制
    Swift4.0复习错误处理
    Swift4.0复习扩展
    Swift4.0复习泛型
    TCP的三次握手(建立连接)和四次挥手(关闭连接)
  • 原文地址:https://www.cnblogs.com/zhang1107/p/3065617.html
Copyright © 2011-2022 走看看