首页 > 其他 > 详细

POJ3678 Katu Puzzle

时间:2019-06-01 17:37:10      阅读:56      评论:0      收藏:0      [点我收藏+]

Katu Puzzle

Katu Puzzle
Time Limit: 1000MSMemory Limit: 65536K
Total Submissions: 12601Accepted: 4627

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:

AND01
000
101
OR01
001
111
XOR01
001
110

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 4
0 1 1 AND
1 2 1 OR
3 2 0 AND
3 0 0 XOR

Sample Output

YES

Hint

X0 = 1, X1 = 1, X2 = 0, X3 = 1.

Source

题解

2-SAT经典题,连边如下:

A AND B = 1   !A->A   !B->B
A AND B = 0   A->!B   B->!A
A OR B = 1      !A->B   !B->A
A OR B = 0      A->!A   B->!B
A XOR B = 1   A->!B !B->A !A->B B->!A
A XOR B = 0   A->B B->A !A->!B !B->!A

然后tarjan求SCC判断有无解即可。

时间复杂度\(O(n+m)\)

#include<iostream>
#include<vector>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;rg char ch=getchar();
    for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
    for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
    return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;

co int N=1006;
int n,m,dfn[N],low[N],num,st[N],top,c[N],cnt;
bool ins[N];
vector<int> e[N*2];

il void add(int x,int y){
    e[x].push_back(y);
}
void tarjan(int x){
    dfn[x]=low[x]=++num;
    st[++top]=x,ins[x]=1;
    for(unsigned i=0;i<e[x].size();++i){
        int y=e[x][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=st[top--],ins[y]=0,c[y]=cnt;
        while(x!=y);
    }
}
int main(){
    read(n),read(m);
    for(int a,b,c;m--;){
        char s[6];
        read(a),read(b),read(c),scanf("%s",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),add(b,a+n);
            else add(a+n,a),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=0;i<n;++i)
        if(!dfn[i]) tarjan(i);
    for(int i=0;i<n;++i)
        if(c[i]==c[i+n]) return puts("NO"),0;
    return puts("YES"),0;
}

POJ3678 Katu Puzzle

原文:https://www.cnblogs.com/autoint/p/10960274.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!