题目链接:
http://poj.org/problem?id=3678
Katu Puzzle
Time Limit: 1000MS |
|
Memory Limit: 65536K |
Total Submissions: 7888 |
|
Accepted: 2888 |
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:
Given 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.Source POJ Founder Monthly Contest – 2008.07.27, Dagger |
[Submit] [Go Back] [Status] [Discuss]
题目意思:
给一幅有向图,每条边代表连接的两个节点的一种运算,并且告诉运算后的值,问能否有一种节点取值,使得各边都满足边的运算。
解题思路:
2-SAT
i代表1 ~i带表0
当i&j==1时,建边 ~i->i ~j->j
当i&j==0时,建边 i->~j j->~i ~i->~j ~j->~i
当i|j==1时,建边 ~i->j ~j->i
当i|j==0时,建边 i->~i j->~j
当i^j==1时,建边 i->~j ~i->j j->~i ~j->i
当i^j==0时,建边 i->j ~i->~j j->i ~j->~i
代码:
//#include<CSpreadSheet.h>#include<iostream>#include<cmath>#include<cstdio>#include<sstream>#include<cstdlib>#include<string>#include<string.h>#include<cstring>#include<algorithm>#include<vector>#include<map>#include<set>#include<stack>#include<list>#include<queue>#include<ctime>#include<bitset>#include<cmath>#define eps 1e-6#define INF 0x3f3f3f3f#define PI acos(-1.0)#define ll __int64#define LL long long#define lson l,m,(rt<<1)#define rson m+1,r,(rt<<1)|1#define M 1000000007//#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define Maxn 2200int n,m;vector<vector<int> >myv;int low[Maxn],dfn[Maxn],sc,bc,dep;int in[Maxn],sta[Maxn];bool iss[Maxn];void tarjan(int cur){ int ne; low[cur]=dfn[cur]=++dep; sta[++sc]=cur; iss[cur]=true; for(int i=0;i<myv[cur].size();i++) { ne=myv[cur][i]; if(!dfn[ne]) { tarjan(ne); low[cur]=min(low[cur],low[ne]); } else if(iss[ne]&&dfn[ne]<low[cur]) low[cur]=dfn[ne]; } if(low[cur]==dfn[cur]) { ++bc; do { ne=sta[sc--]; in[ne]=bc; iss[ne]=false; }while(ne!=cur); }}void solve(){ sc=bc=dep=0; memset(dfn,0,sizeof(dfn)); memset(iss,false,sizeof(iss)); for(int i=0;i<2*n;i++) if(!dfn[i]) tarjan(i);}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); while(~scanf("%d%d",&n,&m)) { myv.clear(); myv.resize(2*n+10); for(int i=1;i<=m;i++) { int a,b,c; char ss[10]; scanf("%d%d%d%s",&a,&b,&c,ss); if(*ss=='A') { if(c==1) { myv[2*a].push_back(2*a+1); myv[2*a+1].push_back(2*b+1); myv[2*b].push_back(2*b+1); myv[2*b+1].push_back(2*a+1); } else { myv[2*a+1].push_back(2*b); myv[2*b+1].push_back(2*a); } } else if(*ss=='O') { if(c==1) { myv[2*a].push_back(2*b+1); myv[2*b].push_back(2*a+1); } else { myv[2*a+1].push_back(2*a); myv[2*a].push_back(2*b); myv[2*b].push_back(2*a); myv[2*b+1].push_back(2*b); } } else { if(c==1) { myv[2*a].push_back(2*b+1); myv[2*a+1].push_back(2*b); myv[2*b].push_back(2*a+1); myv[2*b+1].push_back(2*a); } else { myv[2*a].push_back(2*b); myv[2*a+1].push_back(2*b+1); myv[2*b].push_back(2*a); myv[2*b+1].push_back(2*a+1); } } } solve(); bool ans=true; for(int i=0;i<n;i++) { if(in[2*i]==in[2*i+1]) { ans=false; break; } } if(ans) printf("YES\n"); else printf("NO\n"); } return 0;}
[2-SAT] poj 3678 Katu Puzzle