zoukankan      html  css  js  c++  java
  • Katu Puzzle(POJ3678+2-SAT问题+tarjan缩点)

    题目链接:http://poj.org/problem?id=3678

    题目:

    题意:给你a,b,c,op,op为逻辑运算符或、与、异或,使得a op b = c,让你判断这些运算符是否存在矛盾,不存在输出YES,存在输出NO。

    思路:2-SAT问题。2-SAT问题一般都是每个节点有两种选择,并且在节点中间将存在一定的限制,譬如a为1,那么b必须为1或a为0,b必须为1……而且当一个命题存在时,它的逆否命题必然存在(此处由命题为真,则其逆否命题也为真得证)。我们通过将这些关系转换成有向的边,通过tarjan缩点,我们可以通过判断同一个节点是否它的两种选择在同一个SCC中来决定是否存在矛盾。此题我们假设i为i节点取1,i+n为i节点取0,然后对c和op进行分类讨论,进行建图跑tarjan,从而解决此题。

    代码实现如下:

      1 #include <set>
      2 #include <map>
      3 #include <queue>
      4 #include <stack>
      5 #include <cmath>
      6 #include <bitset>
      7 #include <cstdio>
      8 #include <string>
      9 #include <vector>
     10 #include <cstdlib>
     11 #include <cstring>
     12 #include <iostream>
     13 #include <algorithm>
     14 using namespace std;
     15 
     16 typedef long long ll;
     17 typedef pair<ll, ll> pll;
     18 typedef pair<ll, int> pli;
     19 typedef pair<int, ll> pil;;
     20 typedef pair<int, int> pii;
     21 typedef unsigned long long ull;
     22 
     23 #define lson i<<1
     24 #define rson i<<1|1
     25 #define bug printf("*********
    ");
     26 #define FIN freopen("D://code//in.txt", "r", stdin);
     27 #define debug(x) cout<<"["<<x<<"]" <<endl;
     28 #define IO ios::sync_with_stdio(false),cin.tie(0);
     29 
     30 const double eps = 1e-8;
     31 const int mod = 10007;
     32 const int maxn = 1e6 + 7;
     33 const double pi = acos(-1);
     34 const int inf = 0x3f3f3f3f;
     35 const ll INF = 0x3f3f3f3f3f3f3f;
     36 
     37 int n, m, a, b, c, tot, cnt, num, top;
     38 char op[5];
     39 int head[1007<<1];
     40 int vis[1007<<1], dfn[1007<<1], low[1007<<1], stc[1007<<1], p[1007<<1];
     41 
     42 struct edge {
     43     int v, next;
     44 }ed[maxn<<2];
     45 
     46 void addedge(int u, int v) {
     47     ed[tot].v = v;
     48     ed[tot].next = head[u];
     49     head[u] = tot++;
     50 }
     51 
     52 void tarjan(int x) {
     53     dfn[x] = low[x] = ++num;
     54     stc[++top] = x, vis[x] = 1;
     55     for(int i = head[x]; ~i; i = ed[i].next) {
     56         int y = ed[i].v;
     57         if(!dfn[y]) {
     58             tarjan(y);
     59             low[x] = min(low[x], low[y]);
     60         } else if(vis[y]) {
     61             low[x] = min(low[x], low[y]);
     62         }
     63     }
     64     if(dfn[x] == low[x]) {
     65         int y; cnt++;
     66         do {
     67             y = stc[top--], vis[y] = 0;
     68             p[y] = cnt;
     69         } while(x != y);
     70     }
     71 }
     72 
     73 int main() {
     74     //FIN;
     75     scanf("%d%d", &n, &m);
     76     memset(head, -1, sizeof(head));
     77     for(int i = 1; i <= m; i++) {
     78         scanf("%d%d%d%s", &a, &b, &c, op);
     79         if(op[0] == 'A') {
     80             if(c == 1) {
     81                 addedge(a + n, a);
     82                 addedge(b + n, b);
     83             } else {
     84                 addedge(a, b + n);
     85                 addedge(b, a + n);
     86             }
     87         } else if(op[0] == 'O') {
     88             if(c == 1) {
     89                 addedge(a + n, b);
     90                 addedge(b + n, a);
     91             } else {
     92                 addedge(a, a + n);
     93                 addedge(b, b + n);
     94             }
     95         } else {
     96             if(c == 1) {
     97                 addedge(a, b + n);
     98                 addedge(b, a + n);
     99                 addedge(a + n, b);
    100                 addedge(b + n, a);
    101             } else {
    102                 addedge(a, b);
    103                 addedge(b, a);
    104                 addedge(a + n, b + n);
    105                 addedge(b + n, a + n);
    106             }
    107         }
    108     }
    109     for(int i = 0; i < 2 * n; i++) {
    110         if(!dfn[i]) {
    111             tarjan(i);
    112         }
    113     }
    114     int flag = 1;
    115     for(int i = 0; i < n; i++) {
    116         if(p[i] == p[i+n]) {
    117             flag = 0;
    118             break;
    119         }
    120     }
    121     if(flag) puts("YES");
    122     else puts("NO");
    123     return 0;
    124 }
  • 相关阅读:
    web常用自动化库——selenium总结
    python协程总结
    python多进程总结
    python多线程总结
    Scrapy进阶知识点总结(六)——中间件详解
    Git用法总结
    Scrapy进阶知识点总结(五)——Settings
    Scrapy进阶知识点总结(四)——Item Pipeline
    Scrapy进阶知识点总结(三)——Items与Item Loaders
    Scrapy进阶知识点总结(二)——选择器Selectors
  • 原文地址:https://www.cnblogs.com/Dillonh/p/9405892.html
Copyright © 2011-2022 走看看