• poj 3678 Katu Puzzle 2-SAT 建图入门


    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.
       根据上面直接建图
     
      
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <vector>
      5 #include <string>
      6 #include <algorithm>
      7 #include <queue>
      8 #include <stack>
      9 
     10 using namespace std;
     11 const int maxn = 1e5 + 10;
     12 const int  mod = 1e9 + 7 ;
     13 const int INF = 0x7ffffff;
     14 struct node {
     15     int v, next;
     16 } edge[maxn];
     17 int head[maxn], dfn[maxn], low[maxn];
     18 int s[maxn], belong[maxn], instack[maxn];
     19 int tot, cnt, top, flag, n, m;
     20 void init() {
     21     tot = cnt = top = flag = 0;
     22     memset(s, 0, sizeof(s));
     23     memset(head, -1, sizeof(head));
     24     memset(dfn, 0, sizeof(dfn));
     25     memset(instack, 0, sizeof(instack));
     26 }
     27 void add(int u, int v ) {
     28     edge[tot].v = v;
     29     edge[tot].next = head[u];
     30     head[u] = tot++;
     31 }
     32 void tarjan(int v) {
     33     dfn[v] = low[v] = ++flag;
     34     instack[v] = 1;
     35     s[top++] = v;
     36     for (int i = head[v] ; ~i ; i = edge[i].next ) {
     37         int j = edge[i].v;
     38         if (!dfn[j]) {
     39             tarjan(j);
     40             low[v] = min(low[v], low[j]);
     41         } else if (instack[j]) low[v] = min(low[v], dfn[j]);
     42     }
     43     if (dfn[v] == low[v]) {
     44         cnt++;
     45         int t;
     46         do {
     47             t = s[--top];
     48             instack[t] = 0;
     49             belong[t] = cnt;
     50         } while(t != v) ;
     51     }
     52 }
     53 int check() {
     54     for (int i = 0 ; i < n ; i++)
     55         if (belong[2 * i] == belong[2 * i + 1]) return 0;
     56     return 1;
     57 }
     58 int main() {
     59     while(scanf("%d%d", &n, &m) != EOF) {
     60         if (n == 0 && m == 0) break;
     61         init();
     62         char op[10];
     63         int x, y, c;
     64         for (int i = 0 ; i < m ; i++) {
     65             scanf("%d%d%d%s", &x, &y, &c, op);
     66             if (op[0] == 'A') {
     67                 if (c) {
     68                     add(2 * x + 1, 2 * x);
     69                     add(2 * y + 1, 2 * y);
     70                 } else {
     71                     add(2 * x, 2 * y + 1);
     72                     add(2 * y, 2 * x + 1);
     73                 }
     74             }
     75             if (op[0] == 'O') {
     76                 if (c) {
     77                     add(2 * x + 1, 2 * y);
     78                     add(2 * y + 1, 2 * x);
     79                 } else {
     80                     add(2 * x, 2 * x + 1);
     81                     add(2 * y, 2 * y + 1);
     82                 }
     83             }
     84             if (op[0] == 'X') {
     85                 if (c) {
     86                     add(2 * x, 2 * y + 1);
     87                     add(2 * x + 1, 2 * y);
     88                     add(2 * y, 2 * x + 1);
     89                     add(2 * y + 1, 2 * x);
     90                 } else {
     91                     add(2 * x + 1, 2 * y + 1);
     92                     add(2 * x, 2 * y);
     93                     add(2 * y + 1, 2 * x + 1);
     94                     add(2 * y, 2 * x);
     95                 }
     96             }
     97 
     98         }
     99         for (int i = 0 ; i < 2 * n ; i++)
    100             if (!dfn[i]) tarjan(i);
    101         if (check()) printf("YES
    ");
    102         else printf("NO
    ");
    103     }
    104     return 0;
    105 }
  • 相关阅读:
    Android数据库升级,数据不丢失解决方案
    Android项目中单实例数据库类,解决database is locked
    Android彩蛋效果,微信彩蛋效果
    Android性能优化
    Unable to execute dex: method ID not in [0, 0xffff]: 65536
    Android下载速度计算
    Android中不混淆类中函数
    Android中Parcelable接口用法
    开启Ubuntu Linux下VirtualBox访问USB功能
    touch移动触屏滑动事件
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/9094609.html
Copyright © 2020-2023  润新知