Գրաֆում ամենակարճ ուղին հաշվարկելիս կարելի է այն վերջում նաև վերականգնել:
Դրա համար ամեն այցելվող գագաթի համար կարելի է պահպանել «ծնող» գագաթը: Այսինքն, եթե գագաթ to-ն հերթ ենք ավելացնում այն բանից հետո, երբ մշակել ենք գագաթ v-ն, ապա կարող ենք նշել, որ to-ի «ծնողը» v-ն է: Սա թույլ է տալիս վերջում ամբողջ ուղին վերականգնել: Վերականգնումը սկսում ենք ուղու վերջին գագաթից և քայլում դեպի նրա ծնողը: Հետո գնում ենք ընթացիկ գագաթի ծնողին, և այդպես շարունակ, մինչև կհասնենք գագաթի, որն արդեն ծնող չունի (այդ գագաթը կլինի սկիզբը): Սա կարելի է իրականացնել p (parent) հավելյալ զանգված պահպանելով.
start = int(input()) # սկիզբ գագաթ
d = [-1] * n # հեռավորությունը սկիզբ գագաթից
p = [-1] * n # ծնող գագաթ
q = deque([start]) # գագաթների հերթ
d[start] = 0 # սկիզբ գագաթից մինչեւ սկիզբ գագաթ հեռավորությունը 0 է
while q: # քանի դեռ հերթը դատարկ չէ
v = q.popleft() # հերթից հանել գագաթը
print(v, end=' ') # տպել գագաթը
for to in g[v]: # բոլոր գագաթների համար, որոնք միացված են v-ին
if d[to] == -1: # եթե գագաթը դեռ չի այցելվել
d[to] = d[v] + 1 # (start -> to) = (start -> v) + 1
p[to] = v # գագաթի ծնողը v-ն է
q.append(to) # գագաթը ավելացնել հերթի մեջ
# Ուղու վերականգնում սկիզբից մինչեւ ավարտ
end = int(input()) # ավարտ գագաթ
path = [] # ուղի սկիզբից մինչեւ ավարտ
while end != -1: # քանի դեռ գոյություն ունի ծնող գագաթ
path.append(end) # գագաթը ավելացնել ուղու մեջ
end = p[end] # անցնել ծնող գագաթին
print(*path[::-1], sep=' -> ') # տպել ուղին հակադարձ հերթականությամբ
Այսպիսով, ամեն անգամ հերթ գցելուց հետո նշում ենք տվյալ գագաթի ծնողը p զանգվածում և վերջում «հետ ենք գնում» ամենավերջին գագաթից մինչև սկիզբ: Ու քանի որ ուղու տարրերը ավելացնում ենք վերջից սկիզբ, ապա իրական ուղին տպելու համար այն անհրաժեշտ է շրջել:
Սիմուլյացիան մի քանի մուտքային օրինակների վրա.
n = 4, e = 4
Մուտքային a, b զույգերն են: [(0, 1), (0, 2), (1, 2), (3, 2)]
Սկզբնական գագաթը 3 է, վերջնականը 0
p = [-1, -1, -1, -1], q = [3]
v = 3, q = [] → հերթ ավելացնել բոլոր այն հարևաններին, որոնք դեռ չեն օգտագործվել
p = [-1, -1, 3, -1], q = [2]
v = 2, q = [] → հերթ ավելացնել բոլոր այն հարևաններին, որոնք դեռ չեն օգտագործվել
p = [2, 2, 3, -1], q = [0, 1]
v = 0, q = [1] → հերթ ավելացնել բոլոր այն հարևաններին, որոնք դեռ չեն օգտագործվել
v = 1, q = [] → հերթ ավելացնել բոլոր այն հարևաններին, որոնք դեռ չեն օգտագործվել
Վերակառուցում ենք ուղին
end = 0 → end = 2 → end = 3
Տպում ենք 3 -> 2 -> 0
Ուշադրություն դարձրեք, որ եթե ալգորիթմի վերջում d[end]-ը մնացել է -1, ապա չենք կարող եղել հասնել այդ end գագաթին:
Առաջադրանք: Գտնել Ամենակարճ Ուղին
Ինտերնետը համակարգիչների հավաքածու է, որոնք միմյանց կապակցված են և կարող են տվյալների փոխանակում կատարել: Այստեղ համակարգիչները համարակալված են 1-ից մինչև n, և հայտնի ենpares այն համակարգիչները, որոնք զուգակցված են միմյանց: Էլիսը ցանկանում է ուղարկել հաղորդագրություն Բոբին möglichst արագ տարբերակով: Ուստի հաղորդագրությունն անցնելու ճանապարհը պետք է լինի որքան հնարավոր է կարճ:
Էլիսի համարը a է, իսկ Բոբինը b: Պետք է գտնել համակարգիչների այն հաջորդականությունը, որով հաղորդագրությունը швидко կփոխանցվի Էլիսից Բոբին (այսինքն՝ ամենակարճ ճանապարհը):
Մուտք
Մուտքի առաջին տողում տրված են երկու ամբողջ թիվ n (1 ≤ n ≤ 100 000) և e (1 ≤ e ≤ 100 000) — համակարգիչների քանակը և ցանցում առկա կապերի քանակը:
Հաջորդ տողում տրվում են երկու թվեր a և b (1 ≤ a, b ≤ n):
Հաջորդ e տողերում տրվում են զույգով c1, c2 (1 ≤ c1, c2 ≤ n) թվերը, որոնք ցույց են տալիս, որ c1-ն կապակցված է c2-ի հետ և հակառակը:
Ելք
Պետք է տպել հաղորդագրության փոխանցման ամենակարճ ճանապարհն այնպես, որ համակարգիչների համարները բաժանվեն रिकspace նշանով: Եթե գոյություն ունեն մի քանի հավասարապես կարճ ուղիներ, կարելի է տպել ցանկացածը: