Correctness of Kruskal’s algorithm
By contradiction:
Let T be the tree constructed by the algorithm. then assume that for all MST of G, they are not the same as T. [Assumption]
(let F + e ∗ F+e^* F+e∗ be the edges during the construction at this moment).
Let e ∗ e^* e∗ be the first edge in the construction of T such that F + e ∗ n o t ⊂ a n y M S T F+e^* not \subset any \, MST F+e∗not⊂anyMST, F ⊂ s o m e M S T F\subset some \,MST F⊂someMST
There is an MST T ∗ T^* T∗ that is consistent with F by the definition of e ∗ e^* e∗. Adding e ∗ e* e∗ to T ∗ T^* T∗, creates a cycle.
Note that e ∗ = ( u , v ) e^* = (u, v) e∗=(u,v) is an edge connecting two connected componenets in F, so there is an edge e’ in T ∗ T^* T∗ that is part of the path that connects the two components in F and hence e’ is in the cycle
T ′ = T ∗ + e ∗ − e ′ T' = T^* + e^* -e' T′=T∗+e∗−e′ will be a tree, but w ( e ∗ ) ≤ w ( e ′ ) w(e^*) \le w(e') w(e∗)≤w(e′) [Why? This is because how the algorithm operates. the way we remove elements in S, makes sure edges removed earlier will be lighter than later ones]
Then T’ is an MST that voilates the fact that
F
+
e
∗
F+e^*
F+e∗ is not a subset of any MST (contradiction)
Shortest Path and Matchings
(single source)
Input: a weighted graph G = (V, E, W), with non-negative weight, a source node s and a target node (sink) t.
Output: the shorted path from s to t.
P[s, t]:
s
→
v
1
→
v
2
→
.
.
.
→
v
k
→
t
s \to v_1 \to v_2\to...\to v_k\to t
s→v1→v2→...→vk→t Observation: P[s, v_k] must be contained in P[s, t]
Dijkstra’s Algorithm
Add vertex by vertex. It’s greedy algorithm
init
S = {s}, current = s
dist = [inf, inf, inf,…] dist[s] = 0, // distance to s at current stage
(*)
For each (current, u) in E, u not in S
if dist[u] > dist[current] + w[current, u] update the dist[u]
Put current in S
Let current = $min_j { dist[j] } $ for all j not in S
repeat (*) until t t t is in S S S
Correctnes: At each step, $\forall v\in S, dist(v) = $ shortest path length of s → v s\to v s→v
Induction, if S{s}, then the first step adding c to S is by definition the shorted path from s to c.
If S = {s, n 2 , n 3 , . . . , n k n_2, n_3,...,n_k n2,n3,...,nk} and we are going to add z = n k + 1 z=n_{k+1} z=nk+1 need to show d i s t [ z ] dist[z] dist[z] is the shortest distance to s assuming thisi s true for n 1 n_1 n1 to n k n_k nk. Assume the real shortest path P from s to z leavers S at some vertex u, the next edge is (u,v). We are going to prove length of P = dist[z]
We know that P[s->v] should also be of the same length as the shortest path from s to v
by the algorithm, dist[v] ≤ \le ≤ length of P[s → \to → u] (=dist[u], induction) + w[u, v]
If P[v → \to → z] is not 0 length (non-negative), then
d i s t [ z ] ≥ d i s t [ u ] + w [ u , v ] + dist[z]\ge dist[u] + w[u,v] + dist[z]≥dist[u]+w[u,v]+ length of P [ v → z ] > d i s t [ u ] + w [ u , v ] ≥ d i s t [ v ] [v\to z] > dist[u] + w[u,v] \ge dist[v] [v→z]>dist[u]+w[u,v]≥dist[v]
v should be the next vertex to choose as k+1 'th vertex instead of z. then v has to be z
then length of P = dist[z] (because for all j in S, dist[j] is the shortest path length, and sit[z] = min j ( d i s t [ j ] + w [ j , z ] ) \min_j (dist[j] + w[j,z]) minj(dist[j]+w[j,z]))
[Kinda case by case discussion way of proof]
Implementation:
Adjencency List
Heap
while (t not in S){ // at most N loops
do (*)
}
Remark: Dijkastra’s algorithm doesn’t work for negative weights
In non-negative weight graph: If P is a shortest path in graph G, if there is a cycle, then each edge must be 0 weight
Deal with negative weights in the graph
First be able to detect negative cycles
Bellman-Ford Algorithm
Will detect the negative cycles and will calculate the right result when there is no negative cycle
Some dist vector [inf, 0, inf,…] at the beginning
Introduce the relax step for all edges:
relax(u,v) will test dist[v] > dist[u] + w[u,v], if it is true then dist[v] = dist[u] + w[u,v]
Iteratively run relax until the value of dist stop changing
Q1: what’s the max number of iterations we have to run to ensure the dist is the shortest distance [assume no neg cycle]
Q2: how to detect a negative cycle?
Input: directed or undirected graph G = (V, E, W)
for all v in v{
d[v] = inf; parent[v] = nil;
}
d[s] = 0; parent[s] = s;
for i = 1,...,|V|-1 { // ensure that info on distance from s propagates
for each (u,v) in E { // relax all edges
if (d[u]+w(u,v) < d[v]) then d[v] = d[u] + w[u,v]; parent[v] = u;
}
}
Fact1: if there is no negative cycle, and a shortest path S from s to v of length K, then after K runs of relax, d[k] = length of P
Fact2: there is a negative cycle iff after N-1 runs, with one more run, d[] will still change .