您的位置:首页 > 其它

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

2017-02-22 11:44 513 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=2199

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

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

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

点从2开始,然后就可以愉快的异或啦

#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
,cnt=0;
inline void ins(int u,int v){
cnt++;
e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
}
bool mark
;
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
;
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]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: