POJ 36482-SAT

題名

ポータルPOJ3648ウェディング

回答

ブール変数xix_iを定義しますバツ
xiはtrue⇔参加者iは花嫁席の横にありますx_iはtrue \ Leftrightarrow参加者iは花嫁席の横にあります バツ本当ですか参加によってiはビット新しいマザーシート位置それぞれについて、カップルのをI、JI、Jj、都有¬(xi∧xj)∨(¬xi∧¬xj))\ lnot(x_i \ land x_j)\ lor(\ lnot x_i \ land \ lnot x_j))¬ xバツJ)。¬ X¬ XJ ;花嫁の反対側に同時に現れることができない各ペアi、ji、jについてj、都有¬(¬xi∧¬xj)\ lnot(\ lnot x_i \ land \ lnot x_j)¬ ¬ X¬ XJ ;新郎新婦の場合i、ji、jj、次にxi = 1、xj = 0 x_i = 1、x_j = 0バツ=1 バツJ=0マップを作成するには、T arjanTarjanを使用しますT A R&LT J A N-アルゴリズム2 - SAT 2-SAT2S A T、合計時間計算量はO(N 2)O(N ^ 2)です。O N2

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 35, maxv = maxn * 4, maxe = 4 * (4 * maxn * maxn + maxn);
int N, P, res[maxn * 2];
int tot, head[maxv], to[maxe], nxt[maxe];
int num, dfn[maxv], low[maxv];
int top, st[maxv], scc, sc[maxv];
bool ins[maxv];

inline void add(int x, int y) {
    
     to[++tot] = y, nxt[tot] = head[x], head[x] = tot; }

void tarjan(int x)
{
    
    
    low[x] = dfn[x] = ++num;
    st[++top] = x, ins[x] = 1;
    for (int i = head[x]; i; i = nxt[i])
    {
    
    
        int y = to[i];
        if (!dfn[y])
            tarjan(y), low[x] = min(low[x], low[y]);
        else if (ins[y])
            low[x] = min(low[x], dfn[y]);
    }
    if (low[x] == dfn[x])
    {
    
    
        ++scc;
        int y;
        do
        {
    
    
            y = st[top--], ins[y] = 0, sc[y] = scc;
        } while (y != x);
    }
}
int main()
{
    
    
    while (~scanf("%d%d", &N, &P) && (N | P))
    {
    
    
        tot = num = top = scc = 0;
        memset(head, 0, sizeof(head)), memset(dfn, 0, sizeof(dfn));
        memset(sc, 0, sizeof(sc)), memset(ins, 0, sizeof(ins));
        int n2 = N * 2, lim = N * 4;
        for (int i = 1, x, y; i <= P; ++i)
        {
    
    
            char a, b;
            scanf("%d%c%d%c", &x, &a, &y, &b);
            ++x, ++y;
            if (a == 'w')
                x += N;
            if (b == 'w')
                y += N;
            add(n2 + x, y), add(n2 + y, x);
        }
        add(n2 + N + 1, N + 1), add(1, n2 + 1);
        for (int i = 2; i <= N; ++i)
        {
    
    
            int x = i, y = N + i;
            add(x, n2 + y), add(y, n2 + x), add(n2 + x, y), add(n2 + y, x);
        }
        for (int i = 1; i <= lim; ++i)
            if (!dfn[i])
                tarjan(i);
        bool f = 1;
        for (int i = 1; i <= n2; ++i)
            if (sc[i] == sc[n2 + i])
            {
    
    
                puts("bad luck");
                f = 0;
                break;
            }
        if (f)
        {
    
    
            int k = 0;
            for (int i = 1; i <= n2; ++i)
                if (sc[i] < sc[n2 + i] && i != N + 1)
                    res[++k] = i;
            while (k)
                (res[k] <= N) ? printf("%dh ", res[k] - 1) : printf("%dw ", res[k] - N - 1), --k;
            putchar('\n');
        }
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/neweryyy/article/details/115272817