POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang
Description
Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a boolean operator op (one of AND, OR, XOR) and an integer c (0 ≤ c ≤ 1). One Katu is solvable if one can find each vertex Vi a value Xi (0 ≤ Xi ≤ 1) such that for each edge e(a, b) labeled by op and c, the following formula holds:
Xa op Xb = c
The calculating rules are:
|
|
|
Given a Katu Puzzle, your task is to determine whether it is solvable.
Input
The first line contains two integers N (1 ≤ N ≤ 1000) and M,(0 ≤ M ≤ 1,000,000) indicating the number of vertices and edges.
The following M lines contain three integers a (0 ≤ a < N), b(0 ≤ b < N), c and an operator op each, describing the edges.
Output
Output a line containing "YES" or "NO".
Sample Input
4 4
0 1 1 AND
1 2 1 OR
3 2 0 AND
3 0 0 XOR
Sample Output
YES
Hint
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<cmath>
#include<cstdio>
#include<queue>
#define mem(a , b) memset(a , b , sizeof(a))
using namespace std ;
const int MAXN = 10000 ;
vector<int> G[MAXN * 2] ;
bool mark[MAXN * 2] ;
int S[MAXN] , c ; // 模拟栈
char op[8] ;
int n , m ;
int pan ; // 判断标志
void chu()
{
int i ;
for(i = 0 ; i < n * 2 ; i ++)
G[i].clear() ;
mem(mark , 0) ;
}
void init()
{
chu() ;
pan = 0 ;
int i ;
for(i = 0 ; i < m ; i ++)
{
int a , b , c ;
scanf("%d%d%d" , &a , &b , &c) ;
scanf("%s" , op) ;
if(op[0] == 'A')
{
if(c == 1) // 注意此时建边的方式
{
G[2 * a].push_back(2 * a + 1) ;
G[2 * b].push_back(2 * b + 1) ; }
else
{
G[2 * a + 1].push_back(2 * b) ;
G[2 * b + 1].push_back(2 * a) ;
}
}
else if(op[0] == 'X')
{
if(c == 0)
{
G[2 * a].push_back(2 * b) ;
G[2 * a + 1].push_back(2 * b + 1) ;
G[2 * b].push_back(2 * a) ;
G[2 * b + 1].push_back(2 * a + 1) ;
}
else
{
G[2 * a].push_back(2 * b + 1) ;
G[2 * a + 1].push_back(2 * b) ;
G[2 * b].push_back(2 * a + 1) ;
G[2 * b + 1].push_back(2 * a) ;
}
}
else
{
if(c == 0) // 注意此时建边的方式
{
G[2 * a + 1].push_back(2 * a) ;
G[2 * b + 1].push_back(2 * b) ;
}
else
{
G[2 * a].push_back(2 * b + 1) ;
G[2 * b].push_back(2 * a + 1) ;
}
}
}
}
bool dfs(int x)
{
if(mark[x ^ 1]) return false ;
if(mark[x]) return true ;
mark[x] = true ;
S[c ++] = x ;
int i ;
for(i = 0 ; i < G[x].size() ; i ++)
{
if(!dfs(G[x][i]))
return false ;
}
return true ;
}
void solve()
{
if(pan)
puts("NO") ;
else
{
int i ;
for(i = 0 ; i < n ; i ++)
{
if(!mark[i * 2] && !mark[i * 2 + 1])
{
c = 0 ;
if(!dfs(i * 2))
{
while (c > 0)
{
mark[ S[-- c] ] = false ;
}
if(!dfs(i * 2 + 1))
{
pan = 1 ;
break ;
}
}
}
}
if(pan)
puts("NO") ;
else
puts("YES") ;
}
}
int main()
{
while (scanf("%d%d" , &n , &m) != EOF)
{
init() ;
solve() ;
}
return 0 ;
}
最新文章
- [LeetCode] Decode Ways 解码方法
- 【网络】IP地址格式转换(htonl、ntohl;inet_addr、inet_ntoa)
- MVC 3 IIS7.5 网站发布及IIS配置文件问题处理
- VMware 12 的vmware tools安装和如何使用(系统是CENTOS6.5)
- C#密封类
- 【BZOJ-4568】幸运数字 树链剖分 + 线性基合并
- 常用jQuery代码02
- C#WPF做FTP上传下载获取文件列表
- vmware装redhat该光盘无法被挂载
- Ztack学习笔记(3)-系统启动分析
- socket为send和recv设置超时时间
- Python dir()函数
- Unix文件 I/O(不带缓冲区的)上
- js中变量base64加密传输
- vue 中使用sass实现主体换肤
- 树的子结构(JAVA)
- 导弹拦截 p1020
- JS学习笔记5_DOM
- JS中三目运算符和if else的区别,你弄得明白吗
- 2.QWidget类
热门文章
- 《如何让TT T4模板输出多个文件(VS2010中)》-- access911.net 文章
- 为 Python Server Pages 和 Oracle 构建快速 Web 开发环境。
- Oracle数据库使用存储过程实现分页
- Android Studio代码自己主动提示无效(not available in Power Save mode)
- 第一个Spring MVC程序
- nand烧写分析/内核在启动过程中式如何将这个文件映射成/目录及各子目录的?
- 【枚举+数学】【HDU1271】整数对 难度:五颗星
- 设置grub密码
- BeeswaxException 以及其他问题
- 手工启动oracle EM