首页 > 代码库 > BZOJ 2199: [Usaco2011 Jan]奶牛议会 [2-SAT 判断解]
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 判断解]
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。