poj 3678 Katu Puzzle(2-sat)
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 = cThe 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
X0 = 1, X1 = 1, X2 = 0, X3 = 1.
Source
思路:因为给出结点 a ,b,值 c,还有判断方式OP,这种一看当然就知道是用2SAT做了。为什么说是深刻理解2SAT呢,因为……2SAT中说过,只有关系确定的才能连边,否则不能连边;还有一个重要的是,如果某个条件必须为某个值时,自身与自身的相反条件也要连边,具体看下面解释:
现在设 2*a为1,2*a+1为0;当然 2*b为1,2*b+1为0:
1.当OP为’And‘时:
(1)当c=1时,那么只有a 与 b同时为1时,a AND b才等于1,并且有且只有当a与b都为1时这个条件才成立,所以a与b一定要等1,所以连边<2*a+1,2*a>,<2*b+1,2*b>,表示不管怎么样,a与b的情况都等于1,即:当a等于0时a必等于1,b等于0时b必等于1,这个刚开始我看别人的解题报告就是这么说的,然后自己也没太理解,其实真正的内涵就是强制执行a与b都等于1 !(如果a等于1了的话当然这条边就没用了,如果a等于0的话,那么这条连就可以起到把a强制等于1以符合题目条件情况了,就是如此简单,得慢慢理解)
(2)当c=0时,那么当a等于0时,b可能为0也可以为1,所以是不确定关系,由上面说的一定是确定关系才能连边,所以a为0的情况就不能连边了;当a等于1时,b一定为0才能使 a AND b =0,所以连边:<2*a,2*b+1>,当然还有<2*b,2*a,+1>。
2.当OP为OR时,
(1)当c=1时,那么当a=1时,b=1或者b=0,所以当a=1时出现了两种关系,就是不确定了,就不用连边了;当a=0时,那么b一定=1,所以是确定关系,连边:<2*a+1,2*b>,当然还有<2*b+1,2*a>。
(2)当c=0时,那么只有当a=b=0这个关系,所以这个和上面1(1)情况就一样了,上面是强制执行a=b=1的情况,而这里因为只有a=b=0的情况,所以也要强制执行a=b=0,即连边:<2*a,2*a+1>,<2*b,2*b+1>。
3.当OP为XOR时,因为如果a=1,那么b必=0;a=0,b必=1;b=1,a必=0;b=0,a必=1。如此看,这四个关系都是确定的,所以都要连边,但是其实我们可以不连,一条边都不用连,因为出a=1的时候一定不会再出现a=0了,这四条边是不会产生矛盾的,所以强连通缩点后不会出现belong[2*a]=belong[2*a+1]的情况的,所以连了也没用,只是多加了点判断的时间罢了……这在别人的解题报告里说的是形成了组环了,都是一个意思。比如:a=1,b=0与b=0,a=1在tarjan中会形成一个新的结点,也就是自环,所以……在异或这种情况中只能选择a=0或者a=1,所以不会出现矛盾……故不用连边了!
1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<math.h> 7 #include<algorithm> 8 #include<queue> 9 #include<set> 10 #include<bitset> 11 #include<map> 12 #include<vector> 13 #include<stdlib.h> 14 #include <stack> 15 using namespace std; 16 #define PI acos(-1.0) 17 #define max(a,b) (a) > (b) ? (a) : (b) 18 #define min(a,b) (a) < (b) ? (a) : (b) 19 #define ll long long 20 #define eps 1e-10 21 #define MOD 1000000007 22 #define N 1006 23 #define inf 1e12 24 int n,m; 25 vector<int> e[N]; 26 27 int tot; 28 int head[N]; 29 int vis[N]; 30 int tt; 31 int scc; 32 stack<int>s; 33 int dfn[N],low[N]; 34 int col[N]; 35 struct Node 36 { 37 int from; 38 int to; 39 int next; 40 }edge[N*N]; 41 void init() 42 { 43 tot=0; 44 scc=0; 45 tt=0; 46 memset(head,-1,sizeof(head)); 47 memset(dfn,-1,sizeof(dfn)); 48 memset(low,0,sizeof(low)); 49 memset(vis,0,sizeof(vis)); 50 memset(col,0,sizeof(col)); 51 } 52 void add(int s,int u)//邻接矩阵函数 53 { 54 edge[tot].from=s; 55 edge[tot].to=u; 56 edge[tot].next=head[s]; 57 head[s]=tot++; 58 } 59 void tarjan(int u)//tarjan算法找出图中的所有强连通分支 60 { 61 dfn[u] = low[u]= ++tt; 62 vis[u]=1; 63 s.push(u); 64 int cnt=0; 65 for(int i=head[u];i!=-1;i=edge[i].next) 66 { 67 int v=edge[i].to; 68 if(dfn[v]==-1) 69 { 70 // sum++; 71 tarjan(v); 72 low[u]=min(low[u],low[v]); 73 } 74 else if(vis[v]==1) 75 low[u]=min(low[u],dfn[v]); 76 } 77 if(dfn[u]==low[u]) 78 { 79 int x; 80 scc++; 81 do{ 82 x=s.top(); 83 s.pop(); 84 col[x]=scc; 85 vis[x]=0; 86 }while(x!=u); 87 } 88 } 89 bool two_sat(){ 90 91 for(int i=0;i<2*n;i++){ 92 if(dfn[i]==-1){ 93 tarjan(i); 94 } 95 } 96 for(int i=0;i<n;i++){ 97 if(col[2*i]==col[2*i+1]){ 98 return false; 99 } 100 } 101 return true; 102 } 103 int main() 104 { 105 while(scanf("%d%d",&n,&m)==2){ 106 init(); 107 for(int i=0;i<N;i++) e[i].clear(); 108 while(!s.empty()){ 109 s.pop(); 110 } 111 int a,b,c; 112 char s[6]; 113 for(int i=0;i<m;i++){ 114 scanf("%d%d%d%s",&a,&b,&c,s); 115 if(s[0]=='A'){ 116 if(c==1){ 117 //e[2*a+1].push_back(2*a); 118 //e[2*b+1].push_back(2*b); 119 add(2*a+1,2*a); 120 add(2*b+1,2*b); 121 } 122 else{ 123 //e[2*a].push_back(2*b+1); 124 //e[2*b].push_back(2*a+1); 125 add(2*a,2*b+1); 126 add(2*b,2*a+1); 127 } 128 } 129 else if(s[0]=='O'){ 130 if(c==1){ 131 //e[2*a+1].push_back(2*b); 132 //e[2*b+1].push_back(2*a); 133 add(2*a+1,2*b); 134 add(2*b+1,2*a); 135 } 136 else{ 137 //e[2*a].push_back(2*a+1); 138 //e[2*b].push_back(2*b+1); 139 add(2*a,2*a+1); 140 add(2*b,2*b+1); 141 } 142 } 143 } 144 if(two_sat()){ 145 printf("YES\n"); 146 } 147 else{ 148 printf("NO\n"); 149 } 150 } 151 return 0; 152 }
View Code
转载于:https://www.cnblogs.com/UniqueColor/p/4814122.html
poj 3678 Katu Puzzle(2-sat)相关推荐
- 【2-SAT问题】解题报告:POJ 3678 Katu Puzzle(2-SAT问题的判定)
每个元素只有两种可能的取值,所以是2-SAT的模型. 我们建立2*n个点,x∈[1-n]表示x取0,x∈[n+1-n+n]表示x取1 考虑将所给的关系转化为有向边. u and v=1:u,v都必须是 ...
- POJ - 3678 Katu Puzzle(2-SAT)
题目链接:点击查看 题目大意:给出n个数字,以及m个关系,每个关系只可能是xor.and或or其中之一,问能否有一种赋值满足所有m个关系 题目分析:2-SAT模板题,因为每个关系中的a和b都有一定的关 ...
- POJ 3678 Katu Puzzle
POJ_3678 这是一个2-SAT的问题,很容易能够看出核心变量就是x[i],剩下的工作就是依c的值以及符号分析清楚各个x[i]之间的制约关系. #include<stdio.h>#in ...
- Katu Puzzle(POJ-3678)
Problem Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labe ...
- poj3678 Katu Puzzle 【解法一】
Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...
- POJ 1651 Multiplication Puzzle(类似矩阵连乘 区间dp)
传送门:http://poj.org/problem?id=1651 Multiplication Puzzle Time Limit: 1000MS Memory Limit: 65536K T ...
- poj - 1651 Multiplication Puzzle
简单DP,矩阵相乘,这次尝试自己写一个,居然过了,很好.本来今天还水了poj 1088 二维空间最长下降(上升)序列和 poj 3624 超水0,1背包,也想贴出来凑数的,可是zxpn同志说,这么水的 ...
- POJ - 1651 Multiplication Puzzle (区间dp)
题目链接:Multiplication Puzzle 定义状态dp[i][j]表示将区间[i, j]全部取完所需要的最小代价,答案就是dp[1][n - 2]. 状态转移方程为:dp[i][j] = ...
- POJ 1651 Multiplication Puzzle 区间dp(水
题目链接:点击打开链 题意: 给定一个数组,每次能够选择内部的一个数 i 消除,获得的价值就是 a[i-1] * a[i] * a[i+1] 问最小价值 思路: dp[l,r] = min( dp[l ...
最新文章
- Unable to inject views for 包名.activity
- 如何找到存在Ceph里面的文件
- nodeJs-autoMerge
- 铁钉的blog地址 http://nails.blog.51cto.com
- 万字长文 | 漫谈libco协程设计及实现
- 如何在Hybris Commerce的backoffice里创建扩展字段
- BeanFactory与FactoryBean的区别
- [C++11]可调用对象绑定器
- js+jquery手写弹出提示框
- linux下chkConfig的用法,mysqld开机自启动
- 视觉SLAM笔记(56) 位姿图优化
- 管状合金电阻和片状合金电阻的区别_合金采样电阻的特点及作用
- android studio获取数字签名,Android应用开发Android Studio数字签名打包apk图文步骤教程...
- oracle没有正常启动,Oracledbstart无法正常启动处理办法
- 修改linux系统的open files参数
- 在windows系统下安装linux双系统
- 立创开源 | 基于lm393的模数温度传感器
- html本地修改浏览器自动更新,更改html代码后网页不更新
- 一维非稳态常系数热传导方程(第一类边界条件)
- 【Java】JavaWeb概述
热门文章
- Python之路,day4-Python基础
- 两种类型的Spark RDD task解析以及iterator解析 -- (视频笔记)
- IIS7日志文件位置
- Linux crontab命令
- gcc/g++ 链接库的编译与链接
- hp服务器370G5硬盘列阵,hp DL380 g5创建raid阵列安装系统准备工作
- 安装12G内存读出内存条为3.45G的处理方法
- Python应用实战-Python爬取4000+股票数据,并用plotly绘制了树状热力图(treemap)
- cli3解决 ie11语法错误 vue_基于 Vue + Koa2 + MongoDB + Redis 实现一个完整的登录注册...
- datetime unix php,PHP基于DateTime类解决Unix时间戳与日期互转问题【针对1970年前及2038年后时间戳】...