[伯俊13549 Python]鬼ごっこ3(Gold 5,Daextraor BFS)
アルゴリズムタイプ:マルチアウトレットまたはBFS
草は参考にならずに自分で解いたのか.△
https://www.acmicpc.net/problem/13549
この問題は,0または1に重み付けされた図形と考えられる.
0から10万個のノードがあり、すべてのノードは0または10万以下の範囲で-1、+1、x 2のノードと幹線が接続された図形であり、幹線の重み付け値は0または1である.
重み付けはいずれも0または正であり,あるノードからあるノードへの最短経路重み付けを求めるため,複数のアルゴリズムを用いることができる.
の既存の複数の曲線形式では、現在のノードについて、-1、+1、x 2を隣接ノードとして定義して巡回すればよい点が異なる.そのため、発電機を使います.
この場合,隣接ノードで範囲外の場合を条件文でフィルタリングする必要がある.
最後に,Kノードの最短パス重み付け値を返すと終了する.
SOLVE 2プール概要(BFSプール)
これは BFSを少し変更した接着剤です.
BFSは,幅優先で隣接ノードを探索しながら最短経路を探索するアルゴリズムである.
しかし,この問題の目的は0と1の重みを持つ図形であるため,BFSを用いるにはいくつかの変形を考慮する必要がある.
まず,BFSが重みのないグラフィックで最初にターゲットノードを見つけたときの最短パスであることを確認する.
この問題では、幅優先検索時が最短パスであることを保証するには、グラフィック内のノードの隣接ノードを参照するときに、重み0のノードに先にアクセスする必要があります.
同じレイヤにあるノードでは、ウェイト0のノードは、同じレイヤに入る他のノードに比べて経路の長さが減少し、少なくともこれ以上増加しないように、一歩一歩行うことができる.
したがって、隣接ノードブラウズ時に重み0のノードから優先アクセスを開始するように設計されている場合、BFSの「未アクセスノード優先ブラウズ幅の論理」に従って最短パスを見つけることができる.
勉強するところ、難しいところダエストロで問題を解くのは難しくないが、BFSで問題を解くのは正確ではない.他の人の解答を参考にして、BFSで解答してみましたが、この過程でダエストラとBFSの概念の間にいくつかの混同点が現れ、両者の違いをもっと詳しく学びました.基礎がしっかりしていることを実感しました.
草は参考にならずに自分で解いたのか.△
https://www.acmicpc.net/problem/13549
SOLVE 1
다익스트라 풀이
import sys
import heapq
input = sys.stdin.readline
INF = float('inf')
N, K = map(int, input().split())
# 인접 노드들을 iterable한 값으로 리턴하기 위한 제너레이터 함수
# 코드가 간단해짐
def move(x):
yield (x-1, 1)
yield (x+1, 1)
yield (2*x, 0)
# 다익스트라 알고리즘
def N_to_K(N, K):
SSSP = [INF]*(100001)
SSSP[N] = 0
q = [(0, N)]
while q:
cnt_time, cnt_x = heapq.heappop(q)
if cnt_time > SSSP[cnt_x]:
continue
# 0부터 100000까지의 모든 노드들은, 조건 범위 안에서
# 자신의 -1, +1, *2의 인접 노드를 가짐
# 그래서 제너레이터를 통해 직접 인접 노드를 구하여 순회하면 됨
for adc_x, adc_time in move(cnt_x):
cal_time = cnt_time + adc_time
# 인접 노드로 구한 값이 조건 범위 안에 있어야 함
if 0 <= adc_x <= 100000 and cal_time < SSSP[adc_x]:
SSSP[adc_x] = cal_time
heapq.heappush(q, (cal_time, adc_x))
return SSSP[K]
print(N_to_K(N, K))
SOLVE 2
BFS 풀이
import sys
from collections import deque
input = sys.stdin.readline
N, K = map(int, input().split())
# BFS는 한 번 방문한 노드는 다시 방문하지 않음
# 따라서 같은 level에 대하여 인접 노드로의
# 가중치가 0인 2*x부터 방문해야 함
def move(x):
yield (2*x, 0)
yield (x-1, 1)
yield (x+1, 1)
def BFS(start):
elapsed = [-1]*(100001)
elapsed[start] = 0
q = deque([start])
while q:
cnt_x = q.popleft()
if cnt_x == K:
return elapsed[K]
for nx, adc_time in move(cnt_x):
cal_time = elapsed[cnt_x] + adc_time
if 0 <= nx <= 100000 and elapsed[nx] == -1:
elapsed[nx] = cal_time
q.append(nx)
print(BFS(N))
SOLVE 1)プールの概要この問題は,0または1に重み付けされた図形と考えられる.
0から10万個のノードがあり、すべてのノードは0または10万以下の範囲で-1、+1、x 2のノードと幹線が接続された図形であり、幹線の重み付け値は0または1である.
重み付けはいずれも0または正であり,あるノードからあるノードへの最短経路重み付けを求めるため,複数のアルゴリズムを用いることができる.
この場合,隣接ノードで範囲外の場合を条件文でフィルタリングする必要がある.
最後に,Kノードの最短パス重み付け値を返すと終了する.
これは
BFSは,幅優先で隣接ノードを探索しながら最短経路を探索するアルゴリズムである.
しかし,この問題の目的は0と1の重みを持つ図形であるため,BFSを用いるにはいくつかの変形を考慮する必要がある.
まず,BFSが重みのないグラフィックで最初にターゲットノードを見つけたときの最短パスであることを確認する.
この問題では、幅優先検索時が最短パスであることを保証するには、グラフィック内のノードの隣接ノードを参照するときに、重み0のノードに先にアクセスする必要があります.
同じレイヤにあるノードでは、ウェイト0のノードは、同じレイヤに入る他のノードに比べて経路の長さが減少し、少なくともこれ以上増加しないように、一歩一歩行うことができる.
したがって、隣接ノードブラウズ時に重み0のノードから優先アクセスを開始するように設計されている場合、BFSの「未アクセスノード優先ブラウズ幅の論理」に従って最短パスを見つけることができる.
Reference
この問題について([伯俊13549 Python]鬼ごっこ3(Gold 5,Daextraor BFS)), 我々は、より多くの情報をここで見つけました https://velog.io/@ledcost/백준-13549-파이썬-숨바꼭질-3-골드-5-다익스트라-or-BFSテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol