====== درخت کوتاهترین مسیر و ویژگیهای آن ======
===== تعریف =====
گراف وزن دار، همبند و بدون جهت $G$ را در نظر بگیرید. برای $G$، یک درخت کوتاهترین مسیر از رأس $v$، یک زیر درخت فراگیر و ریشهدار از راس $v$ مثل $T$ است؛ طوری که به ازای هر رأس $u$ از $T$، طول مسیر یکتای $u, v$ در درخت، برابر با طول کوتاهترین مسیر بین $u, v$ در $G$ باشد. توجه کنید که به ازای یک $G$ و $v$، ممکن است بیش از یک درخت کوتاهترین مسیر وجود داشته باشد.
اگر $G$ دور با وزن منفی داشته باشد، نمیتوانیم هیچ درخت کوتاهترین مسیری برای هیچکدام از راسهای آن پیدا کنیم (چرا؟). اما اگر $G$ دور با وزن منفی نداشته باشد، به ازای هر رأس $G$، حداقل یک درخت کوتاهترین مسیر وجود دارد.
----
===== الگوریتم =====
برای پیدا کردن درخت کوتاهترین مسیر برای یک ریشهی تعیین شده مثل $v$، باید ابتدا به ازای هر رأس $u$، طول کوتاهترین مسیر بین $u, v$ را محاسبه کنیم. این فاصله را $dist[u]$ مینامیم. یک یال از $a$ به $b$ با وزن $w$ میتواند در درخت وجود داشته باشد اگر
$$dist[b] = dist[a] + w$$
باشد.
برای محاسبهکردن $dist[u]$-ها میتوان از الگوریتمهایی مثل [[آموزش:الگوریتم:الگوریتم_دایکسترا|الگوریتم دایکسترا]] و [[آموزش:الگوریتم:الگوریتم_بلمن-فورد|بلمن-فورد]] استفاده کرد.
یک راهکار، پیدا کردن همهی یالهای ممکن یرای درخت و سپس استفاده از الگوریتمهای مثل [[آموزش:الگوریتم:جستوجوی_سطحاول|bfs]] و [[آموزش:الگوریتم:جستوجوی_عمقاول|dfs]] برای یافتن یک درخت پوشا است.
راهکاری دیگر، تعیین کردن پدر هر رأس مثل $u$ در درخت ($par[u]$)، هنگام اجرا کردن الگوریتم دایکسترا یا بلمن-فورد است؛ به این صورت که در ابتدا به ازای همهی $u$-ها $par[u] = -1$ و $dist[u] = \infty$ قرار میدهیم. سپس هرگاه مقدار جدید برای $dist[u]$ پیدا کردیم، $par[u]$ را برابر با رأسی قرار میدهیم که مقدار $dist[u]$ را از روی آن آپدیت کردهایم.
در حالت خاص، وقتی وزن همهی یالهای گراف، واحد باشد (یا به عبارت دیگر گراف وزندار نباشد)، درخت $bfs$ با ریشهی $v$، یک درخت کوتاهترین مسیر برای $v$ است.
----
===== پیچیدگی الگوریتم =====
بسته به استفاده کردن از الگوریتمهای دایکسترا و بلمن-فورد، پیچیدگی الگوریتم نیز مانند آنها میشود.
----
===== شبه کد با پیادهسازی دایکسترا =====
Function Dijkstra(v):
dist[v] = 0
For each vertex u in Graph:
If u != v
dist[u] = infinity
par[u] = -1
End if
End for
While T != 0 :
u := vertex not in T with min dist[u]
Add u to T
For each neighbor k of u:
If(dist[k] != dist[u]+w[u][k]):
dist[k] = dist[u]+w[u][k]
par[k] = u
End for
End while
End Function
----
===== شبه کد با پیادهسازی بلمن-فورد =====
Function BellmanFord(list vertices, list edges, vertex v)
// Step 1: initialize graph
For each vertex u in vertices:
If u ≠ v :
dist[u] = infinty
par[u] = -1
End if
End for
// Step 2: relax edges repeatedly
For i from 1 to size(vertices) – 1:
For each edge (u, k) with weight w in edges:
If dist[u] + w < dist[k]:
dist[k] = dist[u] + w
par[k] = u
End if
End for
End for
End Function
----
===== مسائل نمونه =====
===== مراجع =====