BZOJ 2199: [Usaco2011 Jan]奶牛议会 [2-SAT 判断解]

Posted Candy?

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 2199: [Usaco2011 Jan]奶牛议会 [2-SAT 判断解]相关的知识,希望对你有一定的参考价值。

http://www.lydsy.com/JudgeOnline/problem.php?id=2199

题意:裸的2-SAT,但是问每个变量在所有解中是只能为真还是只能为假还是既可以为真又可以为假


 

这样的话求$SCC$的做法就不好做了

于是只能用$naive$做法了,枚举每个变量选择真假然后$dfs$一遍看看是否可行

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=2005,M=2e5+5;
typedef long long ll;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<0||c>9){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}
inline void get(int &x,char &c){
    c=getchar();
    while(c!=h&&c!=m) c=getchar();
    x=read()<<1;
}
int n,m,x,y,vx,vy;
char s[3];
struct edge{
    int v,ne;
}e[M];
int h[N],cnt=0;
inline void ins(int u,int v){
    cnt++;
    e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
}
bool mark[N];
bool dfs(int u){
    if(mark[u^1]) return false;
    if(mark[u]) return true;
    mark[u]=1;
    for(int i=h[u];i;i=e[i].ne)
        if(!dfs(e[i].v)) return false;
    return true;
}
bool check(int u){
    memset(mark,0,sizeof(mark));
    return dfs(u);
}
char ans[N];
int main(){
    freopen("in","r",stdin);
    n=read();m=read();
    for(int i=1;i<=m;i++){
        x=read()<<1;scanf("%s",s);vx=s[0]==Y;
        y=read()<<1;scanf("%s",s);vy=s[0]==Y;
        x|=vx;y|=vy;
        ins(x^1,y);ins(y^1,x);
    }
    for(int i=1;i<=n;i++){
        int p=check(i<<1),q=check(i<<1|1);
        if(!p&&!q){puts("IMPOSSIBLE");return 0;}
        else if(p&&q) ans[i]=?;
        else if(q) ans[i]=Y;
        else ans[i]=N;
    }
    for(int i=1;i<=n;i++) putchar(ans[i]);
}

 

以上是关于BZOJ 2199: [Usaco2011 Jan]奶牛议会 [2-SAT 判断解]的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ2199: [Usaco2011 Jan]奶牛议会

BZOJ 2199: [Usaco2011 Jan]奶牛议会 [2-SAT 判断解]

bzoj2199/Usaco2011 Jan奶牛议会——2-sat

BZOJ2200: [Usaco2011 Jan]道路和航线

bzoj 4506: [Usaco2016 Jan]Fort Moo

[BZOJ1677][Usaco2005 Jan]Sumsets 求和