문제


https://www.acmicpc.net/problem/4230


풀이


보람이쪽에 앉는 것을 True, 철승이쪽에 앉는 것을 False라고 하면, 각 부부 a, b에 대해 a -> !b, !a -> b, b -> !a, !b -> a이다.

또한 불륜 커플 c, d에 대해 !c -> d, !d -> c를 만족해야 한다.


코드


import sys


def dfs(cur):
    global idx, scc_num
    visit[cur] = idx
    low = idx
    idx += 1
    stack.append(cur)

    for nxt in graph[cur]:
        if not visit[nxt]:
            low = min(low, dfs(nxt))
        elif not finish[nxt]:
            low = min(low, visit[nxt])

    if low == visit[cur]:
        while stack:
            top = stack.pop()
            finish[top] = 1
            scc_idx[top] = scc_num
            if cur == top:
                break

        scc_num += 1

    return low


while True:
    n, m = map(int, sys.stdin.readline().split())
    if (n, m) == (0, 0):
        break

    graph = [[] for _ in range(4 * n + 1)]

    graph[1].append(-1)
    graph[-2].append(2)
    
    for i in range(2, n + 1):
        graph[2 * i - 1].append(-2 * i)
        graph[2 * i].append(-2 * i + 1)
        graph[-2 * i + 1].append(2 * i)
        graph[-2 * i].append(2 * i - 1)
    
    for _ in range(m):
        a, b = sys.stdin.readline().split()
        a = 2 * int(a[:-1]) + 1 + (a[-1] == 'w')
        b = 2 * int(b[:-1]) + 1 + (b[-1] == 'w')
        graph[-a].append(b)
        graph[-b].append(a)
    
    stack = []
    scc_num = 1
    scc_idx = [0] * (4 * n + 1)
    finish = [0] * (4 * n + 1)
    visit = [0] * (4 * n + 1)
    idx = 1

    for i in range(1, 4 * n + 1):
        if not visit[i]:
            dfs(i)

    res = [0] * (2 * n + 1)
    for i in range(1, 2 * n + 1):
        if scc_idx[i] == scc_idx[-i]:
            print('bad luck')
            break
        if scc_idx[i] < scc_idx[-i]:
            res[i] = 1
    else:
        for i in range(3, 2 * n + 1):
            if res[i]:
                print(str((i - 1) // 2) + 'wh'[i % 2], end=' ')
        print()

Leave a comment