bzoj1823_2-SAT
来源:互联网 发布:activiti实战源码 编辑:程序博客网 时间:2024/05/05 10:26
练手用裸题, 用最基本的2-SAT算法即可。 题目要求的是对于任意一组要求至少满足其一, 则不妨设要求的事件分别为xi、xj, 则连一条有向边2i+1->2j, 这里2i+1表示xi为假, 那么如果要满足要求则xj必为真, 同理, 再连一条2j+1->2i, 图的构造完成。
基本思路只要考虑每个没有被赋值的变量就行了, 比如, 点xi未赋值时, 将其赋为真, 并沿从这里发出的边向下搜索同时赋为真, 当出现一个点xj中2j和2j+1均为真时, 说明之前的xi为真不成立, 则重新赋为假。 若当前考虑变量无论为真还是为假都矛盾, 那么该问题无解, 输出"BAD"。
上述方法的具体复杂度我不太清楚, 不过上限应该是O(n²), 用tarjan做的话应该也是可以的, 对于大数据可能更优, 这里不给出tarjan代码。
#include <cstdio>#include <cstring>#include <algorithm>#define N 1000 + 10#define M 10000 + 10using namespace std;struct edge{ int to, next;}e[M];int n, m, num, top, p[N], st[N], flag[N];int read(){ char c = getchar(); int x = 0; while(c < '0' || c > '9') c = getchar(); while(c >= '0' && c <= '9') { (x *= 10) += c - '0'; c = getchar(); } return x;}int exread(){ char c = getchar(); while(1) { if (c == 'm') return 1; else if (c == 'h') return 0; c = getchar(); }}void add(int x, int y){ e[++num].to = y; e[num].next = p[x]; p[x] = num;}void init(){ int x, y; top = num = 0; memset(p, 0, sizeof p); memset(flag, false, sizeof flag); n = 2 * read(), m = read(); for (int i = 1; i <= m; ++i) { x = exread() + 2 * read(); y = exread() + 2 * read();//瞬间发现了快速读入的神奇用法 add(x ^ 1, y); add(y ^ 1, x); }}bool dfs(int x){ if (flag[x^1]) return false; if (flag[x]) return true; flag[x] = true; st[++top] = x; for (int i = p[x]; i; i = e[i].next) if (!dfs(e[i].to)) return false; return true;}void deal(){ for (int i = 1; i <= n; ++i) if (!flag[i*2+1] && !flag[i*2]) { top = 0; if (!dfs(i*2)) { while(top > 0) flag[st[top--]] = false; if (!dfs(i*2+1)) { printf("BAD\n"); return; } } } printf("GOOD\n");}int main(){ int t = read(); while(t--) { init(); deal(); } return 0;}
0 0
- bzoj1823_2-SAT
- SAT
- sat
- 2-sat
- 【2-SAT】
- 2-SAT
- 2 - sat
- 2-SAT
- 2-SAT
- 2-Sat
- 2-SAT
- 2-sat
- 2-sat
- 2-SAT
- 2-Sat
- 2-SAT
- 2-SAT
- 2-SAT
- Coursera台大机器学习课程笔记5 -- Theory of Generalization
- CocoaPods安装和使用教程
- java数据结构
- Android中service的使用,前台服务
- 高精度算法
- bzoj1823_2-SAT
- 【Tsinsen】A1255. 拉拉队排练 【Palindromic Tree】
- 判断溢出
- Blog之旅
- MyEclipse8.6.1+spket1.6.23+extjs4.2.1
- linux启动后,默认有以下系统进程
- 大家好个妇科工具发
- [LeetCode] Symmetric Tree(对称镜像树的判别)
- Eclipse 配置 JAD