您的位置:首页 > 其它

POJ 3678 - Katu Puzzle(2-SAT)

2015-04-01 21:23 323 查看
题目:

http://poj.org/problem?id=3678

题意:

有一个n元素的集合, 给出元素之间的关系,(and,or, xor),求出是否满足有满足这样关系的集合.

思路:

2-SAT, 每一个点只能取0/1.

规律:     a and b ==1 , !a->a , !b -> b (a=1, b=1)

            a and b ==0 , a->!b , b->!a  (a=0, b=0)

            a or b ==1 , !a->b , !b->a 

            a or b ==0 , a->!a , b->!b  (a=0, b=0)

            a xor b ==1 , a->!b,!b->a,!a->b,b->!a  ( xor 可以不加边的,因为存在如果a=1,那么b必=0;a=0,b必=1;b=1,a必=0;b=0,a必=1。所以出现a=1时就

            a xor b ==0 , a->b,b->a,!a->!b,!b->!a  不会出现a=0的情况,边之间不会矛盾,所以不存在belong[a]=belong[a+n]的情况.另一种说法是形成                           自环,a=0,b=1和b=1,a=0.)

AC.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>

using namespace std;
const int MAXN = 20005;
const int MAXM = 2e6+5;
int n, m;
struct edge {
int to, next;
}edge[MAXM];
int head[MAXN], tot;

void init()
{
tot = 0;
memset(head, -1, sizeof(head));
}

void addedge(int u, int v)
{
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
}
int low[MAXN], dfn[MAXN], belong[MAXN];
int scc, Index;
stack<int> S;

void tarjan(int u)
{
int v;
low[u] = dfn[u] = ++Index;
S.push(u);
for(int i = head[u]; i != -1; i = edge[i].next) {
v = edge[i].to;
if(!dfn[v]) {
tarjan(v);
if(low[u] > low[v]) low[u] = low[v];
}
else if(!belong[v] && low[u] > dfn[v]) {
low[u] = dfn[v];
}
}
if(low[u] == dfn[u]) {
scc++;
do {
v = S.top(); S.pop();
belong[v] = scc;
}while(v != u);
}
}
bool solve()
{
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(belong, 0, sizeof(belong));

Index = scc = 0;
for(int i = 0; i < 2*n; ++i) {
if(!dfn[i]) tarjan(i);
}

for(int i = 0; i < n; ++i) {
if(belong[i] == belong[n+i]) return false;
}
return true;
}
int main()
{
//freopen("in", "r", stdin);
while(~scanf("%d %d", &n, &m)) {
init();
int u, v, d;
char f[5];

for(int i = 0; i < m; ++i) {
scanf("%d %d %d %s", &u, &v, &d, f);
if(f[0] == 'A') {
if(d == 1) {
addedge(n+u, u);
addedge(n+v, v);
}
else {
addedge(u, n+v);
addedge(v, n+u);
}
}
if(f[0] == 'O') {
if(d == 1) {
addedge(n+u, v);
addedge(n+v, u);
}
else {
//addedge(n+u, n+v);
addedge(u, n+u);
addedge(v, n+v);
}
}
//            if(f[0] == 'X') {
//                if(d == 1) {
//                    addedge(u, n+v);
//                    addedge(v, n+u);
//                    addedge(n+u, v);
//                    addedge(n+v, u);
//                }
//                else {
//                    addedge(n+u, n+v);
//                    addedge(v+n, n+u);
//                    addedge(u, v);
//                    addedge(v, u);
//                }
//            }
}

if(solve() ) {
printf("YES\n");
}
else printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  POJ