公式
G - Minimum XOR Path 解説
by
G - Minimum XOR Path 解説
by
toam
まずは頂点 \(1\) から始まる単純パスがどれくらいあるかを考えます.グラフが完全グラフ(\(M=N(N-1)/2\) のとき)だった場合,単純パスに含まれる頂点列 \((v_1,v_2,\ldots,v_k)\) としてあり得るものは \(v_1=1\) かつ \(v_i\neq v_j(i\neq j)\) を満たすものであり,これを満たすものは \({}_{N-1}P_0+{}_{N-1}P_1+\ldots+{}_{N-1}P_{N-1}\) 通りです(\({}_nP_r\) は異なる \(n\) 個のものから \(k\) 個選んで並べる方法の総数).この値は \(\Theta((N-1)!)\) であり,\(N=10\) のとき約 \(10^6\) となります.したがって,あり得る単純パスを全て調べることができます.
単純パスを全部列挙するには DFS が有効です.(最後に訪れた頂点,訪問したかどうかを確認する配列,すでに通った辺に書かれたラベルの総 XOR)を持ちながら DFS をすることで答えを求めることができます.実装例も参考にしてください.
N, M = map(int, input().split())
G = [[] * N for i in range(N)] # 隣接頂点リスト.(頂点, 辺のラベル)をペアで持つ.
for i in range(M):
u, v, w = map(int, input().split())
u -= 1
v -= 1
G[u].append((v, w))
G[v].append((u, w))
ans = 1 << 60
visited = [False] * N # 訪問済みかどうかを持つリスト
def dfs(v, xor):
global ans
visited[v] = True # 頂点 v を訪問済みにする
# もし今いる頂点が N - 1 なら答えを更新する
if v == N - 1:
ans = min(ans, xor)
for u, w in G[v]:
# もし頂点 u に訪れていないなら,頂点 u に進む
if not visited[u]:
dfs(u, xor ^ w)
visited[v] = False # 訪問済みを解除する
dfs(0, 0)
print(ans)
投稿日時:
最終更新:
