• POJ_3678 Katu Puzzle (2SAT)


      重点是怎么建图,纠结了一天看2-SAT的资料...

    a 表示1, a'表示0,则:

    1、a and b = 1,  a' -> a, b'-> b   (a b 同时为1 )

    2、a and b = 0,  a -> b', b -> a'    (a b 不同时为1)

    3、a  or  b  = 1,  a' -> b, b' -> a    (a b不同时为0)

    4、a  or  b  = 0, a -> a', b -> b'      (a b同时为0 同1)

    5、a xor  b = 1, a -> b', b -> a', a' -> b, b' -> a   (a b 不相等)

    6、a xor  b = 0, a -> b, b -> a, a' -> b', b' -> a'   (a b 相等)

    以1为例:a ^ b = (a V a) ^ (b V b) 因为 A V B 建图为 ~A -> B, ~B -> A, 这里把B换成A就是 ~A -> A,同理, ~B -> B

    另一个关于a and b = 1,  a' -> a, b'-> b 的解释:http://blog.sina.com.cn/s/blog_68629c7701010gf1.html

    渣代码:

    View Code
     1 #include <iostream>
    2 #include <cstdio>
    3 #include <cstring>
    4 #include <stack>
    5 #include <string>
    6
    7 using namespace std;
    8
    9 const int N = 2005;
    10 const int M = 1000005;
    11
    12 struct node {
    13 int next;
    14 int to;
    15 } g[M];
    16
    17 int head[N], scc[N];
    18 int dfn[N], low[N];
    19 int t, cnt, ind;
    20 bool vis[N];
    21
    22 stack<int> s;
    23
    24 void init() {
    25 for(int i = 0; i < N; i++) {
    26 head[i] = scc[i] = dfn[i] = low[i] = vis[i] = 0;
    27 }
    28 t = 1; ind = cnt = 0;
    29 }
    30
    31 void add(int u, int v) {
    32 g[t].to = v; g[t].next = head[u]; head[u] = t++;
    33 }
    34
    35 void tarjan(int u) {
    36 int v, i;
    37 dfn[u] = low[u] = ++ind;
    38 vis[u] = true; s.push(u);
    39 for(i = head[u]; i; i = g[i].next) {
    40 v = g[i].to;
    41 if(!dfn[v]) {
    42 tarjan(v);
    43 low[u] = min(low[u], low[v]);
    44 } else if(vis[v]) {
    45 low[u] = min(low[u], dfn[v]);
    46 }
    47 }
    48 if(low[u] == dfn[u]) {
    49 cnt++;
    50 do {
    51 v = s.top(); s.pop();
    52 scc[v] = cnt;
    53 vis[v] = false;
    54 } while(v != u);
    55 }
    56 }
    57
    58 int main() {
    59 //freopen("data.in", "r", stdin);
    60
    61 int n, m, i;
    62 int a, b, c;
    63 bool flag;
    64 string str;
    65 while(~scanf("%d%d", &n, &m)) {
    66 init();
    67 while(m--) {
    68 cin >> a >> b >> c >> str;
    69 //cout << a << " " << b << " " << c << " " << str << endl;
    70 if(str == "AND") {
    71 if(c) {add(a, a + n); add(b, b + n);}
    72 else {add(a + n, b); add(b + n, a);}
    73 } else if(str == "OR") {
    74 if(c) {add(a, b + n); add(b, a + n);}
    75 else {add(a + n, a); add(b + n, b);}
    76 } else if(str == "XOR") {
    77 if(c) {add(a + n, b); add(a, b + n); add(b, a + n); add(b + n, a);}
    78 else {add(a, b); add(b, a); add(a + n, b + n); add(b + n, a + n);}
    79 }
    80 }
    81 for(i = 0; i < 2*n; i++) {
    82 if(!dfn[i]) tarjan(i);
    83 }
    84 for(flag = true, i = 0; i < n; i++) {
    85 if(scc[i] == scc[i + n]) {
    86 cout << "NO" << endl;
    87 flag = false; break;
    88 }
    89 }
    90 if(flag) cout << "YES" << endl;
    91 }
    92 return 0;
    93 }



  • 相关阅读:
    C语言实现字母接龙的小程序
    求教有关C++中子对象析构的问题
    Leaflet中使用leafletsidebar插件实现侧边栏效果
    Leaflet中使用LeafletMiniMap插件实现小地图效果
    Leaflet中使用leafletsearch插件实现搜索定位效果
    Leaflet中使用awesomemarkers插件显示带图标的marker
    Leaflet中使用Leaflet.Spin插件实现地图加载等待效果
    Leaflet中使用Leaflet.Pin插件实现图层要素编辑效果
    Leaflet中使用Leaflet.contextmenu插件实现地图上添加鼠标右键菜单
    Leaflet中使用Leaflet.MagnifyingGlass实现放大镜效果
  • 原文地址:https://www.cnblogs.com/vongang/p/2352246.html
Copyright © 2020-2023  润新知