【小结】2-sat
来源:互联网 发布:淘宝换货 编辑:程序博客网 时间:2024/06/06 09:06
2−sat 小结
2−sat 解决的是可满足性问题,并且每个合取范式中的文字个数不多于2 个。- 形式为:
(a∨¬b)∧(¬c∨¬d)∧(¬a∨d)⋯ - 将所有
a∨b 改成(¬a⇒b)∧(¬b⇒a) - 建边,每个变量
a 对应两个点a 和a+n - 如果存在
cmp[a]==cmp[a+n] 不成立,否则成立。且如果cmp[a]>cmp[a+n] ,令a=true ,否则令a=false 即为原式的一组解。
#include <cstdio>#include <iostream>#include <cstring>#include <vector>#include <stack>#include <algorithm>using namespace std;const int MAX = 1024;vector<int> G[MAX];vector<int> rG[MAX];stack<int> S;bool vis[MAX];int cmp[MAX];int V;inline void add_edge(int u, int v){ G[u].push_back(v); rG[v].push_back(u);}void dfs(int v){ vis[v] = true; for (vector<int>::iterator it = G[v].begin(); it != G[v].end(); ++it) { if (!vis[*it]) { dfs(*it); } } S.push(v);}void rdfs(int v, int k){ vis[v] = true; cmp[v] = k; for (int i = 0; i < rG[v].size(); ++i) { if (!vis[rG[v][i]]) { rdfs(rG[v][i], k); } }}int scc(){ memset(vis, false, sizeof(vis)); for (int i = 1; i <= V; ++i) { if (!vis[i]) { dfs(i); } } memset(vis, false, sizeof(vis)); int k = 0; while (!S.empty()) { int p = S.top(); S.pop(); if (!vis[p]) { rdfs(p, ++k); } } return k;}int main(){ /* * add_edge(u, v) * N nodes --> V = 2 * N * ... */ /* * EXAMPLE: solve (a V !b) ^ (b V c) ^ (!c V !a) */ int N = 3; V = N << 1; add_edge(3, 4); add_edge(1, 0); add_edge(4, 2); add_edge(5, 1); add_edge(2, 3); add_edge(0, 5); scc(); bool ok = true; for (int i = 1; i <= N; ++i) { if (cmp[i] == cmp[i + N]) { ok = false; break; } } if (ok) { puts("YES"); for (int i = 1; i <= N; ++i) { printf("%s ", cmp[i] > cmp[i + N] ? "true" : "false"); } puts(""); } else { puts("NO"); } return 0;}
POJ3683 Priest John′s Busiest Day
- 问牧师能不能忙过来
- 对婚礼
x ,记在开始举行仪式
为x=true ,则可根据冲突关系,得出方程,求解即可。
#include <cstdio>#include <cstring>#include <vector>#include <stack>#include <algorithm>using namespace std;const int MAX = 2048;vector<int> G[MAX];vector<int> rG[MAX];stack<int> stk;bool vis[MAX];int cmp[MAX];int V;inline void init(){ for (int i = 1; i <= V; ++i) { G[i].clear(); rG[i].clear(); }}inline void add_edge(int u, int v){ G[u].push_back(v); rG[v].push_back(u);}void dfs(int u){ vis[u] = true; for (int i = 0; i < G[u].size(); ++i) { if (!vis[G[u][i]]) { dfs(G[u][i]); } } stk.push(u);}void rdfs(int u, int k){ vis[u] = true; cmp[u] = k; for (int i = 0; i < rG[u].size(); ++i) { if (!vis[rG[u][i]]) { rdfs(rG[u][i], k); } }}int scc(){ memset(vis, false, sizeof(vis)); for (int i = 1; i <= V; ++i) { if (!vis[i]) { dfs(i); } } memset(vis, false, sizeof(vis)); int k = 0; while (!stk.empty()) { int p = stk.top(); stk.pop(); if (!vis[p]) { rdfs(p, ++k); } } return k;}int S[MAX >> 1], T[MAX >> 1], D[MAX >> 1];inline bool error(int l1, int r1, int l2, int r2){ return l1 > l2 ? r2 > l1 : r1 > l2;}void gao(int n){ V = n << 1; for (int i = 1; i <= n; ++i) { for (int j = i + 1; j <= n; ++j) { if (error(S[i], S[i] + D[i], S[j], S[j] + D[j])) { add_edge(i, j + n); add_edge(j, i + n); } if (error(S[i], S[i] + D[i], T[j] - D[j], T[j])) { add_edge(i, j); add_edge(j + n, i + n); } if (error(T[i] - D[i], T[i], S[j], S[j] + D[j])) { add_edge(i + n, j + n); add_edge(j, i); } if (error(T[i] - D[i], T[i], T[j] - D[j], T[j])) { add_edge(i + n, j); add_edge(j + n, i); } } } scc(); //printf("%d\n", scc()); //scc(); for (int i = 1; i <= n; ++i) { if (cmp[i] == cmp[i + n]) { puts("NO"); return; } } puts("YES"); for (int i = 1; i <= n; ++i) { if (cmp[i] > cmp[i + n]) { printf("%02d:%02d %02d:%02d\n", S[i] / 60, S[i] % 60, (S[i] + D[i]) / 60, (S[i] + D[i]) % 60); } else { printf("%02d:%02d %02d:%02d\n", (T[i] - D[i]) / 60, (T[i] - D[i]) % 60, T[i] / 60, T[i] % 60); } }}int main(){ int N; while (~scanf(" %d", &N)) { int h, m; for (int i = 1; i <= N; ++i) { scanf(" %d:%d", &h, &m); S[i] = h * 60 + m; scanf(" %d:%d", &h, &m); T[i] = h * 60 + m; scanf(" %d", D + i); //printf("%d:[%d, %d]:%d\n", i, S[i], T[i], D[i]); } gao(N); } return 0;}
HDU3062
#include <bits/stdc++.h>using namespace std;const int MAX = 1024;vector<int> G[MAX << 1];vector<int> rG[MAX << 1];bool vis[MAX << 1];int cmp[MAX << 1];stack<int> stk;int V;inline void add_edge(int u, int v){ G[u].push_back(v); rG[v].push_back(u);}void dfs(int u){ vis[u] = true; for (int i = 0; i < G[u].size(); ++i) { if (!vis[G[u][i]]) { dfs(G[u][i]); } } stk.push(u);}void dfs2(int u, int k){ vis[u] = true; cmp[u] = k; for (int i = 0; i < rG[u].size(); ++i) { if (!vis[rG[u][i]]) { dfs2(rG[u][i], k); } }}int scc(){ memset(vis, false, sizeof(vis)); for (int i = 1; i <= V; ++i) { if (!vis[i]) { dfs(i); } } memset(vis, false, sizeof(vis)); int k = 0; while (!stk.empty()) { int p = stk.top(); stk.pop(); if (!vis[p]) { dfs2(p, ++k); } } return k;}bool gao(int n){ scc(); for (int i = 1; i <= n; ++i) { if (cmp[i] == cmp[i + n]) { return false; } } return true;}inline void read(int& x){ char ch; while ((ch = getchar()) < '0' || ch > '9'); x = ch - '0'; while ((ch = getchar()) >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; }}int main(){ int n, m; while (~scanf(" %d %d", &n, &m)) { V = n << 1; for (int i = 1; i <= V; ++i) { G[i].clear(); rG[i].clear(); } int a1, a2, c1, c2; while (m--) { //scanf(" %d %d %d %d", &a1, &a2, &c1, &c2); read(a1); read(a2); read(c1); read(c2); if (c1 > 0) { a1 += n; } if (c2 > 0) { a2 += n; } /* * !a1 V !a2 * <-> ((a1 -> !a2) V (a2 -> !a1)) */ add_edge(a1, a2 > n ? a2 - n : a2 + n); add_edge(a2, a1 > n ? a1 - n : a1 + n); } puts(gao(n) ? "YES" : "NO"); } return 0;}
HDU 1824
#include <cstdio>#include <iostream>#include <cstring>#include <vector>#include <stack>#include <algorithm>using namespace std;const int MAX = 1024 * 3 * 2;vector<int> G[MAX];vector<int> rG[MAX];stack<int> S;bool vis[MAX];int cmp[MAX];int V;inline void add_edge(int u, int v){ G[u].push_back(v); rG[v].push_back(u);}void dfs(int v){ vis[v] = true; for (vector<int>::iterator it = G[v].begin(); it != G[v].end(); ++it) { if (!vis[*it]) { dfs(*it); } } S.push(v);}void rdfs(int v, int k){ vis[v] = true; cmp[v] = k; for (int i = 0; i < rG[v].size(); ++i) { if (!vis[rG[v][i]]) { rdfs(rG[v][i], k); } }}int scc(){ memset(vis, false, sizeof(vis)); for (int i = 1; i <= V; ++i) { if (!vis[i]) { dfs(i); } } memset(vis, false, sizeof(vis)); int k = 0; while (!S.empty()) { int p = S.top(); S.pop(); if (!vis[p]) { rdfs(p, ++k); } } return k;}bool gao(int N){ scc(); for (int i = 1; i <= N; ++i) { if (cmp[i] == cmp[i + N]) { return false; } } return true;}int main(){ int T, M; while (~scanf(" %d %d", &T, &M)) { V = T * 3 * 2; int N = T * 3; for (int i = 0; i <= V; ++i) { G[i].clear(); rG[i].clear(); } int c, a, b; for (int i = 1; i <= T; ++i) { scanf(" %d %d %d", &c, &a, &b); ++c, ++a, ++b; add_edge(c + N, a); add_edge(c + N, b); add_edge(a + N, c); add_edge(b + N, c); add_edge(c, a + N); add_edge(c, b + N); add_edge(a, c + N); add_edge(b, c + N); } for (int i = 1; i <= M; ++i) { scanf(" %d %d", &a, &b); ++a, ++b; add_edge(a, b + N); add_edge(b, a + N); } puts(gao(N) ? "yes" : "no"); } return 0;}
POJ 3207
#include <cstdio>#include <iostream>#include <cstring>#include <vector>#include <stack>#include <algorithm>using namespace std;const int MAX = 1024;vector<int> G[MAX];vector<int> rG[MAX];stack<int> S;bool vis[MAX];int cmp[MAX];pair<int, int> line[MAX >> 1];int V;inline void add_edge(int u, int v){ G[u].push_back(v); rG[v].push_back(u);}void dfs(int v){ vis[v] = true; for (vector<int>::iterator it = G[v].begin(); it != G[v].end(); ++it) { if (!vis[*it]) { dfs(*it); } } S.push(v);}void rdfs(int v, int k){ vis[v] = true; cmp[v] = k; for (int i = 0; i < rG[v].size(); ++i) { if (!vis[rG[v][i]]) { rdfs(rG[v][i], k); } }}int scc(){ memset(vis, false, sizeof(vis)); for (int i = 1; i <= V; ++i) { if (!vis[i]) { dfs(i); } } memset(vis, false, sizeof(vis)); int k = 0; while (!S.empty()) { int p = S.top(); S.pop(); if (!vis[p]) { rdfs(p, ++k); } } return k;}bool gao(int n){ scc(); for (int i = 1; i <= n; ++i) { if (cmp[i] == cmp[i + n]) { return false; } } return true;}bool error(int x1, int y1, int x2, int y2){ int xx = min(x1, y1); int yy = min(x1, y1); return (x2 > xx && x2 > yy) || (y2 > xx && y2 > yy) || (x2 > xx && x2 < yy) || (y2 > xx && y2 < yy) || (x2 < xx && x2 < yy) || (y2 < xx && y2 < yy);}int main(){ int n, m; while (~scanf(" %d %d", &n, &m)) { V = m << 1; for (int i = 1; i <= V; ++i) { G[i].clear(); rG[i].clear(); } int a, b; for (int i = 1; i <= m; ++i) { scanf(" %d %d", &line[i].first, &line[i].second); ++line[i].first, ++line[i].second; } for (int i = 1; i <= m; ++i) { for (int j = i + 1; j <= m; ++j) { if (error(line[i].first, line[i].second, line[j].first, line[j].second)) { printf("error at (%d, %d)\n", i, j); //add_edge add_edge(i, j + m); add_edge(j, i + m); } } } puts(gao(m) ? "panda is telling the truth..." : "the evil panda is lying again"); for (int i = 1; i <= m; ++i) { if (cmp[i] > cmp[i + m]) { printf("true "); } else { printf("false "); } } puts(""); } return 0;}
0 0
- 【小结】2-sat
- 【2-SAT】2sat问题小结
- 2-SAT的一些小结
- 2-SAT的一些小结
- 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
- ZOJ 3765 Lights (SPLAY)
- hdu2044(组合数学)
- 【转载】豆瓣最受欢迎的书评——《透明的哀伤》
- 第一周第四天([大小写变换问题][判断是否为email][求对角线的值] [生成数组][数字中添加逗号][生成10个两位随机数,然后再进行排序] [复制数组||将指定数组的指定范围复制到新的数组])
- NYoj 动态规划 聪明的KK
- 【小结】2-sat
- 【android】android studio下二维码类库zxing精简包的配置及第三方类库的导入
- Android StageFrightMediaScanner源代码解析
- mysql 1449 : The user specified as a definer ('root'@'%') does not exist 解决方法
- 1059. Prime Factors (25)
- GCD—互斥锁实现单例
- <七> Linux 文件与目录管理
- Java中实现复制文件或文件夹
- 053第256题