poj3678(给定异或组求是否存在能够组成满足条件的ai)

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

题意:给定m组i和j的AND,OR,XOR组运算,判断是否存在序列满足条件

分析:注意范围0<=ci<=1,0<=ai<=1;

   将i设为0,i‘设为1,分类讨论建立2-SAT模型即可

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<math.h>
using namespace std;
#define pb push_back
const int M=2e3+3;
int n,m;
vector<int>g[M],rg[M],cb;
int vis[M],cmp[M];
char s[10];
void py(){ puts("YES"); }
void pn(){ puts("NO"); }
void init(){
    for(int i=0;i<=2*n;i++) g[i].clear(),rg[i].clear(),cmp[i]=0,vis[i]=0;
    cb.clear();
}
void addedge(int u,int v){
    g[u].pb(v);
    rg[v].pb(u);
}
void dfs(int u){
    vis[u]=1;
    for(int i=0;i<(int)g[u].size();i++)if(!vis[g[u][i]]) dfs(g[u][i]);
    cb.pb(u);
}
void rdfs(int u,int k){
    vis[u]=1;
    cmp[u]=k;
    for(int i=0;i<(int)rg[u].size();i++)if(!vis[rg[u][i]]) rdfs(rg[u][i],k);

}
bool scc(){
    for(int i=0;i<2*n;i++)
        if(!vis[i])
            dfs(i);
    memset(vis,0,sizeof(vis));
    int k=0;
    for(int i=(int)cb.size()-1;i>=0;i--) if(!vis[i]) rdfs(cb[i],++k);

    for(int i=0;i<2*n;i+=2)
        if(cmp[i]==cmp[i+1])return false;
    return true;
}
int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        while(m--){
            int x,y,c;
            scanf("%d%d%d%s",&x,&y,&c,s);
            if(s[0]=='A'){
                if(c==1){///同时取1
                    addedge(2*x,2*x+1);
                    addedge(2*y,2*y+1);
                }
                else{///不同时取1
                    addedge(2*x+1,2*y);
                    addedge(2*y+1,2*x);
                }
            }
            else if(s[0]=='O'){
                if(c==0){///同时取0
                    addedge(2*x+1,2*x);
                    addedge(2*y+1,2*y);
                }
                else{///不同时取0
                    addedge(2*x,2*y+1);
                    addedge(2*y,2*x+1);
                }
            }
            else{
                if(c==0){///要相同
                    addedge(2*x,2*y);
                    addedge(2*y,2*x);
                    addedge(2*x+1,2*y+1);
                    addedge(2*y+1,2*x+1);
                }
                else{///要不同
                    addedge(2*x,2*y+1);
                    addedge(2*y+1,2*x);
                    addedge(2*y,2*x+1);
                    addedge(2*x+1,2*y);

                }
            }
        }
        if(scc()) py();
        else pn();

    }
    return 0;
}
View Code

 

posted @ 2020-10-15 22:59  starve_to_death  阅读(134)  评论(0编辑  收藏  举报