poj 3678 Katu Puzzle 【2-sat 经典建图】
来源:互联网 发布:linux如何给文件夹改名 编辑:程序博客网 时间:2024/06/06 14:25
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 = c
The calculating rules are:
AND01000101OR01001111XOR01001110Given 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 40 1 1 AND1 2 1 OR3 2 0 AND3 0 0 XOR
Sample Output
YES
Hint
X0 = 1, X1 = 1, X2 = 0, X3 = 1.
题意:给出N个布尔变量,每个变量要么真要么假。现在给出M个关系,问你是否存在一组解满足所有条件。
思路:
一:对于AND
1,c == 1时,则a和b全为真,建边 !a -> a 和 !b -> b;
2,c == 0时,则a和b至少一个为假,建边 a -> !b 和 b -> !a;
二:对于OR
1,c == 1时,则a和b至少一个为真,建边!a -> b 和 !b -> a;
2,c == 0时,则a和b全为假,建边a -> !a 和 b -> !b;
三:对于XOD
1,c == 1时,则a和b不同,建边!a -> b 、!b -> a、a -> !b 、 b -> !a;
2,c == 0时,则a和b相同,建边a -> b 、b -> a、!a -> !b 、 !b -> !a;
建好图,tarjan求SCC 判断是否矛盾即可。
AC代码:
#include <cstdio>#include <cstring>#include <queue>#include <vector>#include <stack>#include <algorithm>#define MAXN 2000+10#define MAXM 400000#define INF 1000000using namespace std;vector<int> G[MAXN];int low[MAXN], dfn[MAXN];int dfs_clock;int sccno[MAXN], scc_cnt;stack<int> S;bool Instack[MAXN];int N, M;void init(){for(int i = 0; i < 2*N; i++) G[i].clear();}void getMap(){int a, b, c;char op[10];while(M--){scanf("%d%d%d%s", &a, &b, &c, op);switch(op[0]){case 'A': if(c == 1)//a,b取1 {G[a + N].push_back(a);G[b + N].push_back(b);}else//a,b至少一个不为真 {G[a].push_back(b + N);G[b].push_back(a + N);}break;case 'O':if(c == 1)//a,b最少有一个为真 {G[b + N].push_back(a);G[a + N].push_back(b);}else//a,b都为假 {G[a].push_back(a + N);G[b].push_back(b + N);}break;case 'X':if(c == 1)//a b 不同值 {G[a + N].push_back(b);G[a].push_back(b + N);G[b].push_back(a + N);G[b + N].push_back(a);}else//a b 同真同假 {G[a].push_back(b);G[b].push_back(a);G[a + N].push_back(b + N);G[b + N].push_back(a + N);}}}}void tarjan(int u, int fa){int v;low[u] = dfn[u] = ++dfs_clock;S.push(u);Instack[u] = true;for(int i = 0; i < G[u].size(); i++){v = G[u][i];if(!dfn[v]){tarjan(v, u);low[u] = min(low[u], low[v]);}else if(Instack[v])low[u] = min(low[u], dfn[v]);}if(low[u] == dfn[u]){scc_cnt++;for(;;){v = S.top(); S.pop();Instack[v] = false;sccno[v] = scc_cnt;if(v == u) break; }}}void find_cut(int l, int r){memset(low, 0, sizeof(low));memset(dfn, 0, sizeof(dfn));memset(sccno, 0, sizeof(sccno));memset(Instack, false, sizeof(Instack));dfs_clock = scc_cnt = 0;for(int i = l; i <= r; i++)if(!dfn[i]) tarjan(i, -1);}void solve(){for(int i = 0; i < N; i++){if(sccno[i] == sccno[i + N]){printf("NO\n");return ;}}printf("YES\n");}int main(){while(scanf("%d%d", &N, &M) != EOF){init();getMap();find_cut(0, 2*N-1);solve();}return 0;}
- poj 3678 Katu Puzzle 【2-sat 经典建图】
- POJ 3678 Katu Puzzle (2-SAT)
- POJ 3678 Katu Puzzle(2-SAT判断)
- poj 3678 Katu Puzzle 2-SAT
- 2-sat->poj 3678 Katu Puzzle
- poj 3678 Katu Puzzle (2-sat)
- POJ 3678 Katu Puzzle(2-SAT)
- poj 3678 2-SAT (Katu Puzzle)
- 【POJ】3678 Katu Puzzle 2-sat
- [2-SAT] poj 3678 Katu Puzzle
- POJ 3678 Katu Puzzle(2-sat)
- POJ 3678 Katu Puzzle(2-sat)
- POJ 3678 Katu Puzzle (2-SAT)
- poj 3678 Katu Puzzle 2-sat
- POJ 3678 - Katu Puzzle(2-SAT)
- POJ 3678 Katu Puzzle 2-SAT
- poj 3678 Katu Puzzle 2-SAT
- POJ 3678 Katu Puzzle(2-SAT)
- poj1611 - The Suspects
- poj 1702 平衡三进制
- PAT (Advanced Level) 1039. Course List for Student (25) 排序,手动写哈希
- 黑马程序员--集合框架
- Android Api Demos登顶之路(三)
- poj 3678 Katu Puzzle 【2-sat 经典建图】
- C语言的inline
- 黑马程序员——Java基础---面向对象2
- poj 2828 Buy Tickets
- Android Studio 1.2.2设置显示行号
- 定时访问网站
- hdu3729 I'm Telling the Truth(二分图最大匹配)
- 基于Linux的智能家居的设计(1)
- 3.1 linux进程 2015/7/22