zoukankan      html  css  js  c++  java
  • POJ 3678

    Katu Puzzle
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 7391   Accepted: 2717

    Description

    Katu Puzzle is presented as a directed graph G(VE) 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 ≤ X≤ 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:

    AND 0 1
    0 0 0
    1 0 1
    OR 0 1
    0 0 1
    1 1 1
    XOR 0 1
    0 0 1
    1 1 0

    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 (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 
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <algorithm>
      5 #include <stack>
      6 
      7 using namespace std;
      8 
      9 const int MAX_N = 1005;
     10 const int edge = 1e6 + 5;
     11 int first[2 * MAX_N],Next[4 * edge],v[4 * edge];
     12 int N,M,dfs_clock,scc_cnt;
     13 int low[2 * MAX_N],pre[2 * MAX_N],cmp[2 * MAX_N];
     14 stack<int > S;
     15 
     16 void dfs(int u) {
     17         low[u] = pre[u] = ++dfs_clock;
     18         S.push(u);
     19         for(int e = first[u]; e != -1; e = Next[e]) {
     20                 if(!pre[ v[e] ]) {
     21                         dfs(v[e]);
     22                         low[u] = min(low[u],low[ v[e] ]);
     23                 } else {
     24                         if(!cmp[ v[e] ]) {
     25                                 low[u] = min(low[u],pre[ v[e] ]);
     26                         }
     27                 }
     28         }
     29 
     30         if(pre[u] == low[u]) {
     31                 ++scc_cnt;
     32                 for(;;) {
     33                         int x = S.top(); S.pop();
     34                         cmp[x] = scc_cnt;
     35                         if(x == u) break;
     36                 }
     37         }
     38 }
     39 
     40 void scc() {
     41         dfs_clock = scc_cnt = 0;
     42         memset(cmp,0,sizeof(cmp));
     43         memset(pre,0,sizeof(pre));
     44 
     45         for(int i = 0; i < 2 * N; ++i) if(!pre[i]) dfs(i);
     46 }
     47 
     48 void add_edge(int id,int u) {
     49         int e = first[u];
     50         Next[id] = e;
     51         first[u] = id;
     52 }
     53 
     54 bool solve() {
     55         scc();
     56         for(int i = 0; i < N; ++i) {
     57                 if(cmp[i] == cmp[N + i]) return false;
     58         }
     59         return true;
     60 }
     61 
     62 void build(int a,int b,int c,char ch[],int &len) {
     63         if(strcmp(ch,"AND") == 0) {
     64                     if(c == 0) {
     65                             v[len] = b;
     66                             add_edge(len++,a + N);
     67                             v[len] = a;
     68                             add_edge(len++,b + N);
     69                     } else {
     70                             v[len] = b + N;
     71                             add_edge(len++,a + N);
     72                             v[len] = a + N;
     73                             add_edge(len++,b + N);
     74                             v[len] = a + N;
     75                             add_edge(len++,a);
     76                             v[len] = b + N;
     77                             add_edge(len++,b);
     78                     }
     79             }
     80             if(strcmp(ch,"OR") == 0) {
     81                     if(c == 0) {
     82                             v[len] = b;
     83                             add_edge(len++,a);
     84                             v[len] = b;
     85                             add_edge(len++,b + N);
     86                             v[len] = a;
     87                             add_edge(len++,b);
     88                             v[len] = a;
     89                             add_edge(len++,a + N);
     90                     } else {
     91                             v[len] = b + N;
     92                             add_edge(len++,a);
     93                             v[len] = a + N;
     94                             add_edge(len++,b);
     95                     }
     96             }
     97             if(strcmp(ch,"XOR") == 0) {
     98                     if(c == 0) {
     99                             v[len] = b;
    100                             add_edge(len++,a);
    101                             v[len] = a + N;
    102                             add_edge(len++,b + N);
    103                             v[len] = a;
    104                             add_edge(len++,b);
    105                             v[len] = b + N;
    106                             add_edge(len++,a + N);
    107                     } else {
    108                             v[len] = b + N;
    109                             add_edge(len++,a);
    110                             v[len] = a + N;
    111                             add_edge(len++,b);
    112                             v[len] = b;
    113                             add_edge(len++,a + N);
    114                             v[len] = a;
    115                             add_edge(len++,b + N);
    116                     }
    117             }
    118 
    119 }
    120 
    121 int main()
    122 {
    123     //freopen("sw.in","r",stdin);
    124     scanf("%d%d",&N,&M);
    125     for(int i = 0; i < 2 * N; ++i) first[i] = -1;
    126     int len = 0;
    127     for(int i = 1; i <= M; ++i) {
    128             int a,b,c;
    129             char ch[10];
    130             scanf("%d%d%d%s",&a,&b,&c,ch);
    131             build(a,b,c,ch,len);
    132 
    133     }
    134 
    135     printf("%s
    ",solve() ? "YES" : "NO");
    136     //cout << "Hello world!" << endl;
    137     return 0;
    138 }
    View Code
  • 相关阅读:
    (转)五大常用算法之二:动态规划算法
    (转)五大常用算法之一:分治算法
    dict
    usaco2
    usaco3
    usaco4
    usaco1
    并查集
    洛谷P1428小鱼比可爱
    洛谷P1967货车运输
  • 原文地址:https://www.cnblogs.com/hyxsolitude/p/3700478.html
Copyright © 2011-2022 走看看