您的位置:首页 > 其它

POJ 3678 Katu Puzzle(2-SAT)

2017-04-04 15:58 423 查看
【题目链接】 http://poj.org/problem?id=3678

【题目大意】

  有一些变量,现在给出一些他们做AND,OR,或者XOR的结果(1或0),
  问这些变量是否存在满足所有结果的解集

【题解】

  每个变量只有两种取值,0和1,所以我们拆点做2-SAT,
  i表示xi取0,i+N表示xi取1
  我们发现对于AND起来等于0的情况,两个变量至少有一个要是0,
  那么就有一个变量为1那么另一个变量必须为1的条件,
  对于AND起来等于1的情况我们发现两个变量必须取1,
  所以要否决取0的情况,我们连边i->i+N,这样我们发现变量i如果被选中,那么一定是无解的,
  这样就可以排除xi取0的情况。
  OR的两种情况和AND恰好相反,处理方式一致。
  对于XOR,如果结果为0,那么表示两个变量是状态相同,那么我们正反点之间均连双向边
  如果结果为1,那么我们将两个变量相反状态之间连双向边。
  最后求SCC判定连接情况即可。

【代码】

#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
const int MAX_V=10000;
int V; //顶点数
vector<int> G[MAX_V]; //图的邻接表表示
vector<int> rG[MAX_V]; //反向图
vector<int> vs; //后序遍历
bool used[MAX_V];
int cmp[MAX_V]; //所属强连通分量的拓扑序
void add_edge(int from,int to){
G[from].push_back(to);
rG[to].push_back(from);
}
void dfs(int v){
used[v]=1;
for(int i=0;i<G[v].size();i++){
if(!used[G[v][i]])dfs(G[v][i]);
}vs.push_back(v);
}
void rdfs(int v,int k){
used[v]=1;
cmp[v]=k;
for(int i=0;i<rG[v].size();i++){
if(!used[rG[v][i]])rdfs(rG[v][i],k);
}
}
int scc(){
memset(used,0,sizeof(used));
vs.clear();
for(int v=0;v<V;v++){if(!used[v])dfs(v);}
memset(used,0,sizeof(used));
int k=0;
for(int i=vs.size()-1;i>=0;i--){
if(!used[vs[i]])rdfs(vs[i],k++);
}return k;
}
int N,M;
int x,y,c;
char op[10];
int solve(){
V=N*2;
// 0~N-1 表示 x取0
// N~N+N-1 表示 x取1
for(int i=0;i<M;i++){
scanf("%d%d%d%s",&x,&y,&c,op);
if(op[0]=='A'){
if(c==0){
add_edge(y+N,x);
add_edge(x+N,y);
}else{
add_edge(x,x+N);
add_edge(y,y+N);
}
}else if(op[0]=='O'){
if(c==0){
add_edge(x+N,x);
add_edge(y+N,y);
}else{
add_edge(x,y+N);
add_edge(y,x+N);
}
}else if(op[0]=='X'){
if(c==0){
add_edge(x,y);
add_edge(y,x);
add_edge(x+N,y+N);
add_edge(y+N,x+N);
}else{
add_edge(x,y+N);
add_edge(y,x+N);
add_edge(x+N,y);
add_edge(y+N,x);
}
}
}int n=scc();
int flag=1;
for(int i=0;i<N;i++)if(cmp[i]==cmp[i+N])flag=0;
puts(flag?"YES":"NO");
}
int main(){
while(~scanf("%d%d",&N,&M)){
solve();
}return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: