zoukankan      html  css  js  c++  java
  • POJ 3678 Katu Puzzle

    POJ_3678

    这是一个2-SAT的问题,很容易能够看出核心变量就是x[i],剩下的工作就是依c的值以及符号分析清楚各个x[i]之间的制约关系。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 2010
    #define MAXM 4000010
    int first[MAXD], next[MAXM], v[MAXM], e, N, M;
    int dfn[MAXD], low[MAXD], cnt, ins[MAXD], s[MAXD], top;
    int color[MAXD], col;
    char oper[][5]={"AND", "OR", "XOR"};
    int search(char *str)
    {
    int i;
    for(i = 0; strcmp(str, oper[i]) != 0; i ++);
    return i;
    }
    void add_path(int i, int j)
    {
    v[e] = j;
    next[e] = first[i];
    first[i] = e;
    e ++;
    }
    void buid(i, j, c, op)
    {
    if(c)
    {
    if(op == 0)
    {
    add_path(2 * i, 2 * i + 1);
    add_path(2 * j, 2 * j + 1);
    }
    else if(op == 1)
    {
    add_path(2 * i, 2 * j + 1);
    add_path(2 * j, 2 * i + 1);
    }
    else if(op == 2)
    {
    add_path(2 * i, 2 * j + 1);
    add_path(2 * i + 1, 2 * j);
    add_path(2 * j, 2 * i + 1);
    add_path(2 * j + 1, 2 * i);
    }
    }
    else if(!c)
    {
    if(op == 0)
    {
    add_path(2 * i + 1, 2 * j);
    add_path(2 * j + 1, 2 * i);
    }
    else if(op == 1)
    {
    add_path(2 * i + 1, 2 * i);
    add_path(2 * j + 1, 2 * j);
    }
    else if(op == 2)
    {
    add_path(2 * i, 2 * j);
    add_path(2 * i + 1, 2 * j + 1);
    add_path(2 * j, 2 * i);
    add_path(2 * j + 1, 2 * i + 1);
    }
    }
    }
    void init()
    {
    int i, j, a, b, c, op;
    char str[5];
    e = 0;
    memset(first, -1, sizeof(first));
    for(i = 0; i < M; i ++)
    {
    scanf("%d%d%d%s", &a, &b, &c, str);
    op = search(str);
    buid(a, b, c, op);
    }
    }
    void tarjan(int u)
    {
    int i;
    dfn[u] = low[u] = ++ cnt;
    for(i = first[u]; i != - 1; i = next[i])
    {
    if(!dfn[v[i]])
    {
    s[top ++] = v[i];
    ins[v[i]] = 1;
    tarjan(v[i]);
    if(low[v[i]] < low[u])
    low[u] = low[v[i]];
    }
    else if(ins[v[i]] && dfn[v[i]] < low[u])
    low[u] = dfn[v[i]];
    }
    if(low[u] == dfn[u])
    {
    for(s[top] = -1; s[top] != u;)
    {
    top --;
    ins[s[top]] = 0;
    color[s[top]] = col;
    }
    col ++;
    }
    }
    int com()
    {
    int i;
    cnt = top = col = 0;
    memset(dfn, 0, sizeof(dfn));
    memset(ins, 0, sizeof(ins));
    for(i = 0; i < 2 * N; i ++)
    if(!dfn[i])
    {
    s[top ++] = i;
    ins[i] = 1;
    tarjan(i);
    }
    for(i = 0; i < 2 * N; i ++)
    if(color[i] == color[i ^ 1])
    return 0;
    return 1;
    }
    int main()
    {
    while(scanf("%d%d", &N, &M) == 2)
    {
    init();
    if(com())
    printf("YES\n");
    else
    printf("NO\n");
    }
    return 0;
    }


  • 相关阅读:
    教会他人,让其成为你的接棒人
    2015年看的52部电影计划
    我的2015年读书计划,每两周读完一本书!
    拯救你的电脑之文件命名规范与目录规划
    出租WiFi到底靠不靠谱?
    使用观察者模式更新Fragment的内容
    android静默安装和智能安装(转)
    Android拨打电话不弹出系统拨号界面总结
    Android通过AIDL和反射调用系统拨打电话和挂断电话
    Android设为系统默认的短信应用
  • 原文地址:https://www.cnblogs.com/staginner/p/2198699.html
Copyright © 2011-2022 走看看