結果

問題 No.1776 Love Triangle 2 (Hard)
ユーザー lam6er
提出日時 2025-03-31 17:31:52
言語 PyPy3
(7.3.15)
結果
MLE  
実行時間 -
コード長 4,566 bytes
コンパイル時間 141 ms
コンパイル使用メモリ 82,656 KB
実行使用メモリ 848,912 KB
最終ジャッジ日時 2025-03-31 17:32:55
合計ジャッジ時間 9,772 ms
ジャッジサーバーID
(参考情報)
judge5 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 4 MLE * 1 -- * 171
権限があれば一括ダウンロードができます

ソースコード

diff #

from collections import deque

def main():
    import sys
    input = sys.stdin.read().split()
    ptr = 0
    N, M = int(input[ptr]), int(input[ptr+1])
    ptr += 2
    X = int(input[ptr])
    Y = int(input[ptr+1])
    Z = int(input[ptr+2])
    ptr += 3

    friends = [set() for _ in range(N + 1)]  # Using 1-based index
    for _ in range(M):
        a = int(input[ptr])
        b = int(input[ptr+1])
        friends[a].add(b)
        friends[b].add(a)
        ptr += 2

    allowed_adj = [[] for _ in range(N + 1)]
    for u in range(1, N + 1):
        allowed = []
        for v in range(1, N + 1):
            if u != v and v not in friends[u]:
                allowed.append(v)
        allowed.sort()
        allowed_adj[u] = allowed

    start_visited = 1 << (X - 1)
    initial_path = [X]
    queue = deque()
    queue.append((X, start_visited, False, False, initial_path))

    visited = dict()
    key = (X, start_visited, False, False)
    visited[key] = initial_path.copy()

    solution = None

    while queue:
        current_node, mask, has_y, has_z, path = queue.popleft()

        if current_node == X and len(path) > 1:
            if has_y and has_z:
                valid = True
                if path[-2] in friends[X]:
                    valid = False
                else:
                    for i in range(len(path) - 1):
                        if path[i + 1] in friends[path[i]]:
                            valid = False
                            break
                    if path[1] in friends[X]:
                        valid = False

                if valid:
                    full_path = path + [X]
                    current_k = len(full_path) - 1
                    if solution is None or current_k < solution[0] or (current_k == solution[0] and full_path < solution[1]):
                        solution = (current_k, full_path)
                    if solution is not None:
                        break

        if solution:
            continue

        if current_node == X and len(path) == 1:
            for next_node in allowed_adj[current_node]:
                if next_node == X:
                    continue
                if (mask & (1 << (next_node - 1))):
                    continue
                new_mask = mask | (1 << (next_node - 1))
                new_has_y = has_y or (next_node == Y)
                new_has_z = has_z or (next_node == Z)
                new_path = path + [next_node]
                new_key = (next_node, new_mask, new_has_y, new_has_z)
                if new_key not in visited:
                    visited[new_key] = new_path
                    queue.append((next_node, new_mask, new_has_y, new_has_z, new_path))
        else:
            for next_node in allowed_adj[current_node]:
                if next_node == X:
                    if current_node in friends[X]:
                        continue
                    new_has_y = has_y
                    new_has_z = has_z
                    if not (new_has_y and new_has_z):
                        continue
                    new_path = path + [X]
                    valid = True
                    if path[1] in friends[X]:
                        valid = False
                    else:
                        for i in range(len(new_path) - 1):
                            u, v = new_path[i], new_path[i + 1]
                            if v in friends[u]:
                                valid = False
                                break
                    if valid:
                        current_k = len(new_path) - 1
                        if solution is None or current_k < solution[0] or (current_k == solution[0] and new_path < solution[1]):
                            solution = (current_k, new_path)
                            break
                else:
                    if (mask & (1 << (next_node - 1))):
                        continue
                    new_mask = mask | (1 << (next_node - 1))
                    new_has_y = has_y or (next_node == Y)
                    new_has_z = has_z or (next_node == Z)
                    new_path = path + [next_node]
                    new_key = (next_node, new_mask, new_has_y, new_has_z)
                    if new_key not in visited:
                        visited[new_key] = new_path
                        queue.append((next_node, new_mask, new_has_y, new_has_z, new_path))

    if solution:
        print(solution[0])
        print(' '.join(map(str, solution[1])))
    else:
        print(-1)

if __name__ == '__main__':
    main()
0