AtCoder Beginner Contest 198 E – Unique Color をPython3で解く

Share

AtCoder上にある問題のうち、AtCoder Problemsでdiff 800以上と判定されているものを順番に解いていく企画。
基本的な考え方は全てコード中のコメントに入れてあるので、参照のこと。

出典:
AtCoder Beginner Contest 198 E – Unique Color

情報を管理しながらDFSでノードをたどっていく問題。

# AtCoder Beginner Contest 198 E - Unique Color
# https://atcoder.jp/contests/abc198/tasks/abc198_e
# tag: グラフ 木 DFS

# 実は当初提出した回答では、色を set で管理し、
# dfs(prev, now, color_set) という感じで set のコピーを
# 引き渡していた。
# が、このやり方だと set が膨れ上がると TLE になる。
# (ダブってるのだけカウントする、というやり方で一応通りはした)

# 既出の色は一律で管理するようにし、木をたどるとともに
# 出し入れしていく、というやり方を取るのが正解だろう。
# その場合、set ではなく dict で数をカウントする形になる。

# 再帰回数の制限を解除しておくこと
import sys
sys.setrecursionlimit(10**9)
from collections import defaultdict
def main():
N = int(input())
colors = list(map(int, input().split()))
path_dat = [list(map(int, input().split())) for _ in range(N-1)]

# 0-indexed に変換しつつ、隣接リストを作成
paths = [[] for _ in range(N)]
for a, b in path_dat:
a -= 1
b -= 1
paths[a].append(b)
paths[b].append(a)

# 現在持っている色の管理
color_cnt = defaultdict(int)

result = []

# 再帰関数
def dfs(prev, now):
# 現在の色が、持っている色になければ、結果に追加
if color_cnt[colors[now]] == 0:
# 結果に追加する際、1-indexed に戻す
result.append(now+1)

# 現在の色を持っている色に追加
color_cnt[colors[now]] += 1

# 各子について再帰
for nxt in paths[now]:
if nxt == prev:
continue
dfs(now, nxt)

# 終わったら、さっき追加した色を削除しておく
color_cnt[colors[now]] -= 1

# スタート地点から開始
# 親を存在しない値 (-1) にしておくといい。
dfs(-1, 0)

for r in sorted(result):
print(r)

main()
Share

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です