poj 3678 Katu Puzzle 2-SAT
题目链接
给n个点,每个点有一个点权0或1, m个条件, 每个条件给出两个点u, v, 给出一个值w,w = 0或1, 给出一个条件s。 s为AND, OR或者XOR。 表示u 和 v经过条件s后得到的值为w。
问能否找到满足条件的点权集合。
因为只有0或1两种条件, 所以转化为2-sat。
我们将原来的点拆成两个点, u代表0, u+n代表1.
如果u, v AND之后为1, 那么说明他们两个都是1, 也就是说他们不能为0。 而让他们不为0, 只需要加一条边u -> u+n, v -> v+n。 这样的话, 选u就要选u+n, 与2-sat的条件是矛盾的。
u, v, OR之后为0同上。
u, v, AND之后为0, 那么说明他们不能同时为1, 所以如果u为1, v一定为0。 加边 u+n -> v, v+n -> u。
u, v, OR之后为1和上面差不多。
u, v XOR之后为1和上面差不多。
u, v XOR之后为0, 说明他们两个相同, 那么我们加边 u+n -> v+n, u->v, v->u, v+n -> u+n。
#include <iostream> #include <vector> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <map> #include <set> #include <string> #include <queue> #include <stack> #include <bitset> using namespace std; #define pb(x) push_back(x) #define ll long long #define mk(x, y) make_pair(x, y) #define lson l, m, rt<<1 #define mem(a) memset(a, 0, sizeof(a)) #define rson m+1, r, rt<<1|1 #define mem1(a) memset(a, -1, sizeof(a)) #define mem2(a) memset(a, 0x3f, sizeof(a)) #define rep(i, n, a) for(int i = a; i<n; i++) #define fi first #define se second typedef pair<int, int> pll; const double PI = acos(-1.0); const double eps = 1e-8; const int mod = 1e9+7; const int inf = 1061109567; const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; const int maxn = 2e6+5; int head[2005], num, n, m, top, cnt, deep; int instack[2005], st[2005], low[2005], dfn[2005], id[2005]; struct node {int to, nextt; }e[maxn*2]; void add(int u, int v) {e[num].to = v, e[num].nextt = head[u], head[u] = num++; } void tarjan(int u) {instack[u] = 1;st[++top] = u;dfn[u] = low[u] = ++deep;for(int i = head[u]; ~i; i = e[i].nextt) {int v = e[i].to;if(!dfn[v]) {tarjan(v);low[u] = min(low[u], low[v]);} else if(instack[v]) {low[u] = min(low[u], dfn[v]);}}int v;if(dfn[u] == low[u]) {++ cnt;do {v = st[top--];instack[v] = 0;id[v] = cnt;} while(v != u);} } void solve() {for(int i = 0; i < n; i++) {if(!dfn[i])tarjan(i);}int flag = 0;for(int i = 0; i<n; i++) {if(id[i] == id[i+n]) {flag = 1;}}if(flag) {puts("NO");} else {puts("YES");} } void read() {char s[5];int u, v, w;for(int i = 0; i<m; i++) {scanf("%d%d%d", &u, &v, &w);scanf("%s", s);if(w) {if(s[0] == 'A') {add(u, u + n);add(v, v + n);} else if(s[0] == 'O') {add(u, v + n);add(v, u + n);} else {add(u, v + n);add(v, u + n);}} else {if(s[0] == 'A') {add(u + n, v);add(v + n, u);} else if(s[0] == 'O') {add(u + n, u);add(v + n, v);} else {add(u, v);add(v, u);add(v + n, u + n);add(u + n, v + n);}}} } void init() {num = top = cnt = deep = 0;mem1(head);mem(instack);mem(dfn);mem(low); } int main() {cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);while(cin>>n>>m) {init();read();solve();}return 0; }
转载于:https://www.cnblogs.com/yohaha/p/5284167.html
poj 3678 Katu Puzzle 2-SAT相关推荐
- 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 ...
- 【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 ...
最新文章
- ios开发 静音键设置_iOS开发,改变系统铃声音量和静音,并非媒体播放音量
- 在ListBox中添加ToggleButton(有IsChecked属性)
- 2.1.1 物理层接口特性、数据通信模型、物理层基本概念(数据、信号、码元 、信源、信道、信宿 、速率、波特、带宽)
- AI应用开发实战 - 手写识别应用入门
- CCF201312-3 最大的矩形(100分)
- 第3章 Python 数字图像处理(DIP) - 灰度变换与空间滤波2 - 图像反转、对数变换
- Burpsuite学习(4) 1
- 还在用 Dockerfile 部署 Spring Boot?out 啦!试试谷歌的大杀器 Jib
- mysql 中间点策略_网易MySQL中间件的负载均衡策略及性能优化
- PL/SQL 结构与实例
- Mirai 新变体利用严重漏洞攻击网络安全设备
- 强化学习 —— gym
- load runner
- HTML创建几个边框,使用HTML5创建多个边框
- 在命令行英雄的浏览器大战中,JavaScript令人惊讶地崛起
- 判断邮箱正确的c语言代码,如何用c语言来识别电子邮箱是否正确
- mocha-only和skip的用法
- 小米3联通电信版解锁(2013062 2013063)刷机包可解账号锁
- 计算机无法从usb启动不了,用u盘启动不了电脑解决方法
- npm 和 yarn 缓存清理