題名
ポータルPOJ3648ウェディング
回答
ブール変数xix_iを定義しますバツ私
xiはtrue⇔参加者iは花嫁席の横にありますx_iはtrue \ Leftrightarrow参加者iは花嫁席の横にあります バツ私本当ですか⇔参加とによってiはビットに新しいマザーシート位置側それぞれについて、カップルのをI、JI、J私、j、都有¬(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、j私、j、次に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-SAT2−S 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;
}