每个元素只有两种可能的取值,所以是2-SAT的模型.
我们建立2*n个点,x∈[1…n]表示x取0,x∈[n+1…n+n]表示x取1
考虑将所给的关系转化为有向边.

  • u and v=1:u,v都必须是1.为了让他们都是1,我们需要让他们为0时出现矛盾,也就是加边(u,u+n),(v,v+n)
  • u and v=0:如果u=1那么v=0,加边(u+n,v).同理,加边(v+n,u)
  • u or v=1:如果u=0那么v=1加边(u,v+n).同理,加边(v,u+n)
  • u or v=0:u,v都必须是0.为了让他们都是0,我们需要让他们为1时出现矛盾,也就是加边(u+n,u),(v+n,v)
  • u xor v=0:u=v,所以加边(u,v),(v,u),(u+n,v+n),(v+n,u+n)
  • u xor v=1:u≠v,所以加边(u,v+n),(v,u+n),(u+n,v),(v+n,u)

图建完之后,跑一遍tarjan求出所有SCC,若出现矛盾(即存在scc[x]==scc[x+n],在同一个强连通分量中说明能互相到达,是一个环,也就是P则Q,那么X既是1又是0所以有矛盾)就不存在解.否则存在.
时间复杂度O(n+m).注意边数点数开足够.

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<math.h>
#include<cstring>
#include<queue>
//#define ls (p<<1)
//#define rs (p<<1|1)
#define over(i,s,t) for(register int i = s;i <= t;++i)
#define lver(i,t,s) for(register int i = t;i >= s;--i)
//#define int __int128
//#define lowbit(p) p&(-p)
using namespace std;typedef long long ll;
typedef pair<int,int> PII;
const ll INF = 1e18;
const int N = 5e3;
const int M = 5e4+7;int head[N],nex[M],ver[M],tot;
//vector<int>scc[N];
int cnt,n,m;
int dfn[N],low[N],num;
int stk[N],top;
int vis[N],c[N];
int in[N],out[N],ansi,anso;
int ins[N];inline void read(int &x){int f=0;x=0;char c=getchar();while(c<'0'||c>'9')f|=c=='-',c=getchar();while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar();x=f?-x:x;
}void add(int x,int y){ver[++tot] = y;nex[tot] = head[x];head[x] = tot;
}void tarjan(int x){dfn[x] = low[x] = ++num;stk[++top] = x,ins[x] = 1;for(int i = head[x];i;i = nex[i]){int y = ver[i];if(!dfn[y]){tarjan(y);low[x] = min(low[x],low[y]);}else if(ins[y])low[x] = min(low[x],dfn[y]);}if(dfn[x] == low[x]){++cnt;int y;do{y = stk[top--];ins[y] = 0;c[y] = cnt;//scc[cnt].push_back(y);}while(x != y);}
}int main()
{cin>>n>>m;while(m--){int a,b,c;char s[7];scanf("%d %d %d %s",&a,&b,&c,s);if(s[0] == 'A'){if(c){//现在只是连起来,最后看是否在同一个强连通分量里,在就说明是一个环 add(a,a+n);add(b,b+n);//虽然有连边但是不一定是在一个强连通分量里 }else {add(a+n,b);add(b+n,a);} }else if(s[0] == 'O'){if(c){add(a,b+n);//至少有1个是1 add(b,a+n);}else {add(a+n,a);//应该都是0 add(b+n,b);} } else {if(c){add(a,b+n);add(b,a+n);add(a+n,b);add(b+n,a);}else {add(a,b);add(b,a);add(a+n,b+n);add(b+n,a+n); }}}for (int i = 1; i <= n; i++)if (!dfn[i]) tarjan(i);for (int i = 1; i <= n; i++)if (c[i] == c[i+n]) {puts("NO");return 0;}puts("YES");return 0;
}

【2-SAT问题】解题报告:POJ 3678 Katu Puzzle(2-SAT问题的判定)相关推荐

  1. 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. POJ - 3678 Katu Puzzle(2-SAT)

    题目链接:点击查看 题目大意:给出n个数字,以及m个关系,每个关系只可能是xor.and或or其中之一,问能否有一种赋值满足所有m个关系 题目分析:2-SAT模板题,因为每个关系中的a和b都有一定的关 ...

  3. POJ 3678 Katu Puzzle

    POJ_3678 这是一个2-SAT的问题,很容易能够看出核心变量就是x[i],剩下的工作就是依c的值以及符号分析清楚各个x[i]之间的制约关系. #include<stdio.h>#in ...

  4. poj解题报告——poj 1528 Perfection

    原题入口 poj 1528 Perfection 题目描述 Perfection Time Limit: 1000MS Memory Limit: 10000K Total Submissions: ...

  5. 解题报告 poj 3207

    1.        题目 POJ 3207 2.        题目实质 平面上,一个圆,圆的边上按顺时针放着n个点.现在要连m条边,比如a,b,那么a到b可以从圆的内部连接,也可以从圆的外部连接.问 ...

  6. 解题报告 poj 2109

    话说,那个题的中文翻译是:开一个高精度数 p 的 n 次方根 k . #include <cstdio> #include <cmath>int main() {double ...

  7. POJ 2800 垂直直方图 解题报告

    POJ 2800 垂直直方图 解题报告 编号:2800   考查点:简单计算题 思路: 用gets()读入4行数据,然后按字符统计,显示的时候有点小处理即可. 提交情况: 感觉POJ的测试数据有点骗人 ...

  8. POJ 2745 显示器 解题报告

    POJ 2745 显示器 解题报告 编号:2745   考查点:模拟 思路:抽象出来,计算器显示是7个笔画,然后建立数组表示各笔画被覆盖情况,不过这个是我看了书之后实现的,方法果真经典. 提交情况:比 ...

  9. Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)

    http://blog.csdn.net/geniusluzh/article/details/6619575 在说Tarjan算法解决桥和边双连通分量问题之前我们先来回顾一下Tarjan算法是如何求 ...

最新文章

  1. keras中重要的函数用法及参数详解
  2. PPT 图片python处理
  3. 8 分钟了解 Kubernetes
  4. word2010页脚页码的总页数修改方法
  5. onselectstart 、onselect区别
  6. 推荐四十多条纯干货 Java 代码优化建议
  7. 异常处理python 空气质量问题_python的异常处理
  8. oracle批量替换保留字,oracle保留字大全
  9. AI学习笔记(十五)自然语言处理基本概念
  10. ❤️《大前端—NPM包管理器》
  11. Quartz的时间配置
  12. 数据库连接失败could not find driver 解决方法
  13. 【气动学】基于matlab改进的遗传和粒子群算法高斯烟羽模型模拟气体扩散【含Matlab源码 1061期】
  14. GPS坐标系转换工具类
  15. uni-app背景图片的设置
  16. 机器学习-支持向量机SVM算法
  17. keras入门教程 1.线性回归建模(快速入门)
  18. 菜鸟菜鸟菜鸟菜鸟编程之路
  19. linux5.8关闭屏幕保护,chia linux
  20. 密码学_SM4国密算法

热门文章

  1. 导师:学AI的不懂计算机视觉,那你别学了
  2. 基于OpenCV实战:对象跟踪
  3. 四则运算 3.0 结对
  4. python 对象拷贝
  5. Java性能调优、LinkedIn容器部署、阿里移动性能调优——首届APMCon精彩演讲先睹为快...
  6. vs code 列编辑模式
  7. angular.foreach 格式
  8. Lync server 2010部署及解决方案
  9. C++用substr()函数消除前后空格
  10. 【Scala-spark.mlib】稠密矩阵和稀疏矩阵的创建及操作