[JSOI2010]满汉全席

Posted _CRしち_のblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[JSOI2010]满汉全席相关的知识,希望对你有一定的参考价值。

又是一道2-SAT裸题(读题比想题久/kk)

/*
m: 0 (i + 0 * n)
h: 1 (i + 1 * n)
*/
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 210;
const int M = 2010;
struct node{
    int pre, to;
}edge[M];
int head[N], tot;
int K;
int n, m;
int dfn[N], low[N], stk[N], top, dep;
int col[N], scc;
bool vis[N];
void tarjan(int x) {
    dfn[x] = low[x] = ++dep;
    stk[++top] = x;
    vis[x] = 1;
    for (int i = head[x]; i; i = edge[i].pre) {
        int y = edge[i].to;
        if (!dfn[y]) {
            tarjan(y);
            low[x] = min(low[x], low[y]);
        } else if (vis[y]) {
            low[x] = min(low[x], dfn[y]);
        }
    }
    if (low[x] == dfn[x]) {
        scc++;
        vis[x] = 0;
        col[x] = scc;
        while (stk[top] != x) {
            col[stk[top]] = scc;
            vis[stk[top]] = 0;
            top--;
        }
        top--;
    }
}
void add(int u, int v) {
    edge[++tot] = node{head[u], v};
    head[u] = tot;
}
int read() {
    int ret = 0, f = 1;
    char ch = getchar();
    while (0 > ch || ch > 9) {
        if (ch == -) f = -1;
        ch = getchar();
    }
    while (0<= ch && ch <= 9) {
        ret = (ret << 1) + (ret << 3) + ch - 0;
        ch = getchar();
    }
    return ret * f;
}
void write(int x) {
    if (x > 9) write(x / 10);
    putchar(x % 10 + 0);
}
void print(int x) {
    if (x < 0) {
        x = -x;
        putchar(-);
    }
    write(x);
    putchar(
);
}
int f(char c) {
    return c == m ? 0 : 1;
}
int main() {
    K = read();
    while (K--) {
        top = scc = 0;
        memset(vis, 0, sizeof(vis));
        memset(col, 0, sizeof(col));
        memset(low, 0, sizeof(low));
        memset(dfn, 0, sizeof(dfn));
        memset(head, 0, sizeof(head));
        tot = 0;
        n = read(); m = read();
        for (int i = 1; i <= m; i++) {
            char s1[5], s2[5];
            scanf("%s%s", s1 + 1, s2 + 1);
            int l1 = strlen(s1 + 1);
            int l2 = strlen(s2 + 1);
            int x = 0, y = 0;
            for (int j = 2; j <= l1; j++) {
                x = (x << 1) + (x << 3) + s1[j] - 0;
            }
            for (int j = 2; j <= l2; j++) {
                y = (y << 1) + (y << 3) + s2[j] - 0;
            }
            int a = f(s1[1]);
            int b = f(s2[1]);
            add(x + (a ^ 1) * n, y + (b & 1) * n);
            add(y + (b ^ 1) * n, x + (a & 1) * n);
        }
        for (int i = 1; i <= n << 1; i++) {
            if (!dfn[i]) {
                tarjan(i);
            }
        }
        bool ans = 1;
        for (int i = 1; i <= n; i++) {
            if (col[i] == col[i + n]) {
                ans = 0;
                break;
            }
        }
        if (ans) puts("GOOD");
        else puts("BAD");
    }
    return 0;
}

 

以上是关于[JSOI2010]满汉全席的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1823 [JSOI2010]满汉全席 2-sat

[JSOI2010]满汉全席

Bzoj : 1823: [JSOI2010]满汉全席

bzoj 1823: [JSOI2010]满汉全席 -- 2-sat

[JSOI2010]满汉全席

[JSOI2010]满汉全席