码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-02-22 12:58:53      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:amp   int   log   http   getch   memset   scan   iostream   ++   

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 判断解]

标签:amp   int   log   http   getch   memset   scan   iostream   ++   

原文地址:http://www.cnblogs.com/candy99/p/6428184.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!