목차

끝말잇기 하실 분!!

ps
링크acmicpc.net/…
출처BOJ
문제 번호26166
문제명끝말잇기 하실 분!!
레벨플래티넘 5
분류

게임 이론

시간복잡도O(n)
인풋사이즈n<=100,000
사용한 언어Python 3.13
제출기록40208KB / 112ms
최고기록112ms
해결날짜2024/12/17

풀이

코드

"""Solution code for "BOJ 26166. 끝말잇기 하실 분!!".

- Problem link: https://www.acmicpc.net/problem/26166
- Solution link: http://www.teferi.net/ps/problems/boj/26166

Tags: [game theory]
"""

import sys

WIN = 0
LOSE = 1
DRAW = 2


def main():
    M = int(sys.stdin.readline())
    words = [sys.stdin.readline().rstrip() for _ in range(M)]

    rev_graph = [[] for _ in range(26)]
    out_deg = [0] * 26
    for word in words:
        u, v = int(word[0], 36) - 10, int(word[-1], 36) - 10
        rev_graph[v].append(u)
        out_deg[u] += 1

    state_by_node = [DRAW] * 26
    stack = []
    for u, deg in enumerate(out_deg):
        if deg == 0:
            state_by_node[u] = LOSE
            stack.append(u)

    while stack:
        v = stack.pop()
        for u in rev_graph[v]:
            if state_by_node[u] != DRAW:
                continue
            if state_by_node[v] == LOSE:
                state_by_node[u] = WIN
                stack.append(u)
                continue
            out_deg[u] -= 1
            if out_deg[u] == 0:
                state_by_node[u] = LOSE
                stack.append(u)

    answer = sorted(
        x for x in words if state_by_node[int(x[-1], 36) - 10] == LOSE
    )
    print(len(answer))
    print('\n'.join(answer))


if __name__ == '__main__':
    main()