87
Weighted Graph Algorithms

Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Embed Size (px)

Citation preview

Page 1: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Weighted Graph Algorithms

Page 2: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Contents 最小生成树

Prim算法 并查集 Kruskal算法

最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法

网络流初步 最大流问题 最小费用最大流

Page 3: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

最小生成树

Page 4: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Minimum Spanning Trees• Given: Connected, undirected, weighted graph, G• Find: Minimum - weight spanning tree, T• Example:

b c

a

d e f

5

11

0

3 1

7

-3

1

a

b c

fed

5

3 -31

0

Acyclic subset of edges(E) that connectsall vertices of G.

Page 5: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Generic Algorithm“Grows” a set A.

A is subset of some MST.

Edge is “safe” if it can be added to A without destroying this invariant.

Generic-MST(G, w)1 A := ;2 while A does not form a MST3 do find a safe edge (u, v) for A4 A := A {(u, v)}5 return A

Generic-MST(G, w)1 A := ;2 while A does not form a MST3 do find a safe edge (u, v) for A4 A := A {(u, v)}5 return A

Page 6: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Ücut partitions vertices intodisjoint sets, S and V – S.

b ca

d e f

5

11

0

3 1

7

-3

2

this edge crosses the cut

a light edge crossing cut(could be more than one)

Definitions

cut respects the edge set {(a, b), (b, c)}

one endpoint is in S and the other is in V – S.

no edge in the set crosses the cut

Page 7: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Proof:Let T be a MST that includes A.Case: (u, v) in T. We’re done.Case: (u, v) not in T. We have the following:

u y

x

v

edge in A

cut

shows edgesin T

Theorem 23.1 in CLRSTheorem 23.1: Let (S, V-S) be any cut that respects A, and let (u, v) be a light edge crossing (S, V-S). Then, (u, v) is safe for A.

Theorem 23.1: Let (S, V-S) be any cut that respects A, and let (u, v) be a light edge crossing (S, V-S). Then, (u, v) is safe for A.

(x, y) crosses cut.Let T´ = T - {(x, y)} {(u, v)}.

Because (u, v) is light for cut,w(u, v) w(x, y). Thus, w(T´) = w(T) - w(x, y) + w(u, v) w(T).

Hence, T´ is also a MST. So, (u, v) is safe for A.

Page 8: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

In general, A will consist of several connected components.

Corollary

Corollary: If (u, v) is a light edge connecting one CC in (V, A)to another CC in (V, A), then (u, v) is safe for A.

Corollary: If (u, v) is a light edge connecting one CC in (V, A)to another CC in (V, A), then (u, v) is safe for A.

Page 9: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example: Kruskal’s Algorithm

Figure: Kruskal’s Algorithm

Page 10: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Kruskal 算法

把所有边排序,记第 i 小的边为 e[i] (0<=i<m)

初始化 MST 为空初始化连通分量,让每个点自成为一个独立的连通分量for (int i=0; i<m; i++) if (e[i].u 和 e[i].v 不在同一个连通分量 ) { 把边 e[i] 加入 MST 合并 e[i].u 和 e[i].v 所在的连通分量 }

Page 11: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

存储结构

int u[maxm],v[maxm],w[maxm];cin >> n >> m; // 输入 n 个顶点 , m 条边for(int e=0;e<m;e++) cin>>u[e]>>v[e]>>w[e];// 排序边int cmp(const int i, const int j){return w[i]<w[j];}int e[m];for(int i=0;i<m; i++) e[i] = i;sort(e, e+m, cmp);

Page 12: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

MST-Kruskal(G, w)

1 A // initially A is empty

2 for each vertex v V[G] // line 2-3 takes O(V) time

3 do Make-Set(v) // create set for each vertex

4 sort the edges of E into nondecreasing order by weight w

5 for each edge (u,v) E, taken in nondecreasing order by weight

6 do if Find-Set(u) Find-Set(v) // u&v on different trees

7 then A A {(u,v)}

8 Union(u,v)

9 return A

Total running time is O(E lg E).

Page 13: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

并查集

Page 14: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

并查集 森林表示法:可以用森林来表示并查集。

森林里的每棵树代表一个集合。 树的根结点就是集合的代表元素。

数组表示的森林 Each entry p[i] in the array represents the parent

of element i, initially p[i] = -1. If i is a root, then p[i] = -1.

查找操作 查找一个元素 u ,只需顺着叶子到根结点的路径找

到 u 所在的根结点,也就确定 u 所在的集合。

Page 15: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Union Eight elements, initially in different sets

1 2 3 4 5 6 70

-1 -1 -1 -1 -1 -1 -1 -1

0 1 2 3 4 5 6 7

Page 16: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Union After union(4,5)

1 2 3 4

5

6 70

-1 -1 -1 -1 -1 4 -1 -1

0 1 2 3 4 5 6 7

Page 17: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Union After union(6,7)

1 2 3 4

5

0

-1 -1 -1 -1 -1 4 -1 6

0 1 2 3 4 5 6 7

6

7

Page 18: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Union After union(4,6)

1 2 3 4

5

0

-1 -1 -1 -1 -1 4 4 6

0 1 2 3 4 5 6 7

6

7

Page 19: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Union Codesint p[maxn];for(int i=0;i<n;i++) p[i] = -1;int find(int x) { return (p[x] == -1) ? x : find(p[x]);}int union(int x, int y){ p[y] = x;}

Page 20: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Quick-Find Now

1 2 3 4

5

0

-1 -1 -1 -1 -1 4 4 6

0 1 2 3 4 5 6 7

6

7

Page 21: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Quick-Find After find(7)

1 2 3 4

5

0

-1 -1 -1 -1 -1 4 4 4

0 1 2 3 4 5 6 7

6 7

Page 22: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Quick-Find

int p[maxn];for(int i=0;i<n;i++) p[i] = -1;int find(int x) { return (p[x] == -1) ? x : p[x]=find(p[x]);}int union(int x, int y){ p[y] = x;}

Page 23: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

更高效的合并策略当 p[i] 值小于 0 ,表明 i 是所在树的根结点(所在集

合的代表元素)。这时用 -p[i] 值计 i 所在树的高度。合并时将矮树合并到高树。

int p[maxn];for(int i=0;i<n;i++) p[i] = -1;int find(int x) { return (p[x] < 0) ? x : p[x]=find(p[x]);}int union(int x, int y){ if (p[x]<p[y]) p[y] = x; //x higher than y else if (p[y]<p[x]) p[x] = y; //y higher than x else {p[y] = x; p[x]--;}}

Page 24: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Kruskal with disjoint setsint cmp(int i, int j) {return w[i]<w[j]};int p[maxn],r[maxm]; int find(int x) {return (p[x] == -1) ? x : p[x]=find(p[x]);}int union(int x, int y) { p[y] = x;}int Kruskal() { int ans = 0; for(int i=0;i<n;i++) p[i] = -1; for(int i=0;i<m;i++) r[i] = i; sort(r,r+m,cmp); for(int i=0;i<m;i++) { int e = r[i], x = find(u[e]), y = find(v[e]); if (x!=y) {ans += w[e]; union(x,y);} } return ans;}

Page 25: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Prim Algorithm

Page 26: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Prim’s Algorithm Builds one tree, so A is always a tree. Starts from an arbitrary “root” r . At each step, adds a light edge crossing cut (VA, V -

VA) to A. VA = vertices that A is incident on.

Page 27: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Prim’s Algorithm Uses a priority queue Q to find a light edge quickly. Each object in Q is a vertex in V - VA. Key of v is minimum weight of any edge (u, v), where u

VA. Then the vertex returned by Extract-Min is v such that

there exists u VA and (u, v) is light edge crossing (VA, V - VA).

Key of v is if v is not adjacent to any vertex in VA.

Page 28: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Q := V[G];for each u Q do

key[u] := od;key[r] := 0;[r] := NIL;while Q do

u := Extract - Min(Q);for each v Adj[u] do

if v Q and w(u, v) < key[v] then [v] := u;

key[v] := w(u, v)fi

odod

Q := V[G];for each u Q do

key[u] := od;key[r] := 0;[r] := NIL;while Q do

u := Extract - Min(Q);for each v Adj[u] do

if v Q and w(u, v) < key[v] then [v] := u;

key[v] := w(u, v)fi

odod

Complexity:Using binary heaps: O(E lg V). Initialization – O(V). Building initial queue – O(V). V Extract-Min’s – O(V lgV). E Decrease-Key’s – O(E lg V). Using Fibonacci heaps: O(E + V lg V).(see book)

Prim’s Algorithm

Note: A = {(v, [v]) : v v - {r} - Q}.

decrease-key operation

Page 29: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

/* very similar to Dijkstra’s algorithm */

v1 v2

v6 v7

v3 v4 v5

2

4

2

1 3 10

7

58 4

61

Example of Prim’s Algorithm

Page 30: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example of Prim’s Algorithm

b/ c/a/0

d/ e/ f/

5

11

0

3 1

7

-3

2

Q = a b c d e f 0

Not in tree

Page 31: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example of Prim’s Algorithm

b/5 c/a/0

d/11 e/ f/

5

11

0

3 1

7

-3

2

Q = b d c e f 5 11

Page 32: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example of Prim’s Algorithm

b/5 c/7a/0

d/11 e/3 f/

5

11

0

3 1

7

-3

2

Q = e c d f 3 7 11

Page 33: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example of Prim’s Algorithm

b/5 c/1a/0

d/0 e/3 f/2

5

11

0

3 1

7

-3

2

Q = d c f 0 1 2

Page 34: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example of Prim’s Algorithm

b/5 c/1a/0

d/0 e/3 f/2

5

11

0

3 1

7

-3

2

Q = c f 1 2

Page 35: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example of Prim’s Algorithm

b/5 c/1a/0

d/0 e/3 f/-3

5

11

0

3 1

7

-3

2

Q = f -3

Page 36: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example of Prim’s Algorithm

b/5 c/1a/0

d/0 e/3 f/-3

5

11

0

3 1

7

-3

2

Q =

Page 37: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example of Prim’s Algorithm

0

b/5 c/1a/0

d/0 e/3 f/-3

5

3 1 -3

Page 38: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Variations on Minimum Spanning Trees Maximum Spanning Trees

Simply negating the weights of all edges and running Prim’s algorithm.

Minimum Product Spanning Trees We seek the spanning tree that minimizes the product

of edge weights. Since lg(ab)=lg(a) + lg(b), the mst on a graph whose

edge weights are replaced with their logarithms gives the answer.

Minimum Bottlenneck Spanning Tree Sometimes we seek a spanning tree that minimizes

the maximum edge weight over all such trees. Every MST has this property.

Page 39: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Single-Source Shortest Paths Given A single source vertex in a weighted, directed graph. Want to compute a shortest path for each possible destination. Similar to BFS.

We will assume either no negative-weight edges, or no reachable negative-weight cycles.

Algorithm will compute a shortest-path tree. Similar to BFS tree.

Page 40: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Outline

General Lemmas and Theorems. DAG algorithm. Dijkstra algorithm. Bellman-Ford algorithm.

Page 41: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Corollary: Let p = SP from s to v, where p = s u v. Then,δ(s, v) = δ(s, u) + w(u, v).

Corollary: Let p = SP from s to v, where p = s u v. Then,δ(s, v) = δ(s, u) + w(u, v).

General Results (Relaxation)Lemma 24.1: Let p = ‹v1, v2, …, vk› be a SP from v1 to vk. Then,pij = ‹vi, vi+1, …, vj› is a SP from vi to vj, where 1 i j k.

Lemma 24.1: Let p = ‹v1, v2, …, vk› be a SP from v1 to vk. Then,pij = ‹vi, vi+1, …, vj› is a SP from vi to vj, where 1 i j k.

So, we have the optimal-substructure property.

Bellman-Ford’s algorithm uses dynamic programming.

Dijkstra’s algorithm uses the greedy approach.

Let δ(u, v) = weight of SP from u to v.

p'

Lemma 24.10: Let s V. For all edges (u,v) E, we haveδ(s, v) δ(s, u) + w(u,v).

Lemma 24.10: Let s V. For all edges (u,v) E, we haveδ(s, v) δ(s, u) + w(u,v).

Page 42: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Relaxation

Initialize(G, s)for each v V[G] do

d[v] := ;[v] := NIL

od;d[s] := 0

Initialize(G, s)for each v V[G] do

d[v] := ;[v] := NIL

od;d[s] := 0

Relax(u, v, w)if d[v] > d[u] + w(u, v) then

d[v] := d[u] + w(u, v);[v] := u

fi

Relax(u, v, w)if d[v] > d[u] + w(u, v) then

d[v] := d[u] + w(u, v);[v] := u

fi

Algorithms keep track of d[v], [v]. Initialized as follows:

These values are changed when an edge (u, v) is relaxed:

Page 43: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Properties of Relaxation d[v], if not , is the length of some path from s to

v. d[v] either stays the same or decreases with

time Therefore, if d[v] = (s, v) at any time, this holds

thereafter Note that d[v] (s, v) always After i iterations of relaxing on all (u,v), if the

shortest path to v has i edges, then d[v] = (s, v).

Page 44: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Properties of RelaxationConsider any algorithm in which d[v], and [v] are first initializedby calling Initialize(G, s) [s is the source], and are only changed bycalling Relax. We have:

Lemma 24.11: ( v:: d[v] (s, v)) is an invariant.Lemma 24.11: ( v:: d[v] (s, v)) is an invariant.

Implies d[v] doesn’t change once d[v] = (s, v).

Proof:Initialize(G, s) establishes invariant. If call to Relax(u, v, w)changes d[v], then it establishes:

d[v] = d[u] + w(u, v) (s, u) + w(u, v) , invariant holds before call. (s, v) , by Lemma 24.10.

Corollary 24.12: If there is no path from s to v, thend[v] = δ(s, v) = is an invariant.

Corollary 24.12: If there is no path from s to v, thend[v] = δ(s, v) = is an invariant.

Page 45: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

More Properties

Lemma 24.14: Let p = SP from s to v, where p = s u v.If d[u] = δ(s, u) holds at any time prior to calling Relax(u, v, w),then d[v] = δ(s, v) holds at all times after the call.

Lemma 24.14: Let p = SP from s to v, where p = s u v.If d[u] = δ(s, u) holds at any time prior to calling Relax(u, v, w),then d[v] = δ(s, v) holds at all times after the call.

p'

Proof:

After the call we have:d[v] d[u] + w(u, v) , by Lemma 24.13. = (s, u) + w(u, v) , d[u] = (s, u) holds. = (s, v) , by corollary to Lemma 24.1.

By Lemma 24.11, d[v] δ(s, v), so d[v] = δ(s, v).

Lemma 24.13: Immediately after relaxing edge (u, v) by callingRelax(u, v, w), we have d[v] d[u] + w(u, v).

Lemma 24.13: Immediately after relaxing edge (u, v) by callingRelax(u, v, w), we have d[v] d[u] + w(u, v).

Page 46: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Predecessor SubgraphLemma 24.16: Assume given graph G has no negative-weight cyclesreachable from s. Let G = predecessor subgraph. G is always atree with root s (i.e., this property is an invariant).

Lemma 24.16: Assume given graph G has no negative-weight cyclesreachable from s. Let G = predecessor subgraph. G is always atree with root s (i.e., this property is an invariant).

Proof:Two proof obligations:

(1) G is acyclic.(2) There exists a unique path from source s to each vertex in V.

Proof of (1):

Suppose there exists a cycle c = ‹v0, v1, …, vk›, where v0 = vk.We have [vi] = vi-1 for i = 1, 2, …, k.

Assume relaxation of (vk-1, vk) created the cycle.We show cycle has a negative weight.

Note: Cycle must be reachable from s. (Why?)

Page 47: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Proof of (1) (Continued)Before call to Relax(vk-1, vk, w):

[vi] = vi-1 for i = 1, …, k–1.

Implies d[vi] was last updated by “d[vi] := d[vi-1] + w(vi-1, vi)”for i = 1, …, k–1.

Implies d[vi] d[vi-1] + w(vi-1, vi) for i = 1, …, k–1.

Because [vk] is changed by call, d[vk] > d[vk-1] + w(vk-1, vk). Thus,

cycle!weight -neg. i.e., 0,)v,w(v ,]d[v]d[v Because

)v,w(v]d[v

))v,w(v](d[v]d[v

k

1ii1i

k

1i1i

k

1ii

k

1i

k

1ii1i1i

k

1i

k

1ii1i1ii

Page 48: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Proof of (2)Proof of (2):

( v: v V:: ( path from s to v)) is an invariant.

So, for any v in V, at least 1 path from s to v.

Show 1 path.

Assume 2 paths.

s u

y

x

z v

impossible!

Page 49: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Lemma 24.17Lemma 24.17: Same conditions as before. Call Initialize & repeatedlycall Relax until d[v] = δ(s, v) for all v in V. Then, G is a shortest-pathtree rooted at s.

Lemma 24.17: Same conditions as before. Call Initialize & repeatedlycall Relax until d[v] = δ(s, v) for all v in V. Then, G is a shortest-pathtree rooted at s.

Proof:

Key Proof Obligation: For all v in V, the unique simple path p froms to v in G (path exists by Lemma 24.16) is a shortest path from s to vin G.

Let p = ‹v0, v1, …, vk›, where v0 = s and vk = v.

We have d[vi] = δ(s, vi) d[vi] d[vi-1] + w(vi-1, vi)

Implies w(vi-1, vi) δ(s, vi) – δ(s, vi-1).

Page 50: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Proof (Continued)

)v, δ(s

)v, δ(s)v, δ(s

))v, δ(s)v, δ(s(

)v,w(v

w(p)

k

0k

1-ii

k

1i

k

1ii1i

So, p is a shortest path.

Page 51: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Bellman-Ford AlgorithmCan have negative-weight edges. Will “detect” reachable negative-weightcycles.

Initialize(G, s);for i := 1 to |V[G]| –1 do

for each (u, v) in E[G] doRelax(u, v, w)

odod;for each (u, v) in E[G] do

if d[v] > d[u] + w(u, v) thenreturn false

fiod;return true

Initialize(G, s);for i := 1 to |V[G]| –1 do

for each (u, v) in E[G] doRelax(u, v, w)

odod;for each (u, v) in E[G] do

if d[v] > d[u] + w(u, v) thenreturn false

fiod;return true

Time Complexityis O(VE).

Page 52: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0

z

u v

x y

6

5

–3

9

7

7

8

–2

–42

Page 53: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0

7

6

z

u v

x y

6

5

–3

9

7

7

8

–2

–42

Page 54: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0

27

46

z

u v

x y

6

5

–3

9

7

7

8

–2

–42

Page 55: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0

27

42

z

u v

x y

6

5

–3

9

7

7

8

–2

–42

Page 56: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0

-27

42

z

u v

x y

6

5

–3

9

7

7

8

–2

–42

Page 57: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Another LookNote: This is essentially dynamic programming.

Let d(i, j) = cost of the shortest path from s to i that is at most j hops.

d(i, j) =

0 if i = s j = 0 if i s j = 0min({d(k, j–1) + w(k, i): i Adj(k)} {d(i, j–1)}) if j > 0

z u v x y 1 2 3 4 50 0 1 0 6 7 2 0 6 4 7 23 0 2 4 7 24 0 2 4 7 –2

j

i

Page 58: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Lemma 24.2Lemma 24.2: Assuming no negative-weight cycles reachable froms, d[v] = (s, v) holds upon termination for all vertices v reachablefrom s.

Lemma 24.2: Assuming no negative-weight cycles reachable froms, d[v] = (s, v) holds upon termination for all vertices v reachablefrom s.

Proof:

Consider a SP p, where p = ‹v0, v1, …, vk›, where v0 = s and vk = v.

Assume k |V| – 1, otherwise p has a cycle.

Claim: d[vi] = (s, vi) holds after the ith pass over edges.Proof follows by induction on i.

By Lemma 24.11, once d[vi] = (s, vi) holds, it continues to hold.

Page 59: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

CorrectnessClaim: Algorithm returns the correct value.

(Part of Theorem 24.4. Other parts of the theorem follow easily from earlier results.)

Case 1: There is no reachable negative-weight cycle.

Upon termination, we have for all (u, v):d[v] = (s, v) , by Lemma 24.2 if v is reachable; d[v] = (s, v) = otherwise. (s, u) + w(u, v) , by Lemma 24.10. = d[u] + w(u, v)

So, algorithm returns true.

Page 60: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Case 2Case 2: There exists a reachable negative-weight cyclec = ‹v0, v1, …, vk›, where v0 = vk.

We have i = 1, …, k w(vi-1, vi) < 0. (*)

Suppose algorithm returns true. Then, d[vi] d[vi-1] + w(vi-1, vi) fori = 1, …, k. Thus,

i = 1, …, k d[vi] i = 1, …, k d[vi-1] + i = 1, …, k w(vi-1, vi)

But, i = 1, …, k d[vi] = i = 1, …, k d[vi-1].

Can show no d[vi] is infinite. Hence, 0 i = 1, …, k w(vi-1, vi).

Contradicts (*). Thus, algorithm returns false.

Page 61: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Shortest Paths in DAGs

Topologically sort vertices in G;Initialize(G, s);for each u in V[G] (in order) do

for each v in Adj[u] doRelax(u, v, w)

odod

Topologically sort vertices in G;Initialize(G, s);for each u in V[G] (in order) do

for each v in Adj[u] doRelax(u, v, w)

odod

Page 62: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Shortest Paths in DAGs

Topologically sort vertices in G;Initialize all dist(.) values to INFdist(s) = 0for each v ∈ V , in linearized order do

dist(v) = min(u,v) E∈ { dist(u) + w(u,v) }

Topologically sort vertices in G;Initialize all dist(.) values to INFdist(s) = 0for each v ∈ V , in linearized order do

dist(v) = min(u,v) E∈ { dist(u) + w(u,v) }

Page 63: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0 r s t u v w

5 2 7 –1 –2

6 1

32

4

Page 64: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0 r s t u v w

5 2 7 –1 –2

6 1

32

4

Page 65: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0 2 6 r s t u v w

5 2 7 –1 –2

6 1

32

4

Page 66: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0 2 6 6 4

r s t u v w5 2 7 –1 –2

6 1

32

4

dist[u]=min{dist[s]+6, dist[t]+7}

Page 67: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0 2 6 5 4

r s t u v w5 2 7 –1 –2

6 1

32

4

Page 68: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0 2 6 5 3

r s t u v w5 2 7 –1 –2

6 1

32

4

Page 69: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0 2 6 5 3

r s t u v w5 2 7 –1 –2

6 1

32

4

Page 70: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Dijkstra’s AlgorithmAssumes no negative-weight edges.

Maintains a set S of vertices whose SP from s has been determined.

Repeatedly selects u in V–S with minimum SP estimate (greedy choice).

Store V–S in priority queue Q.Initialize(G, s);S := ;Q := V[G];while Q do

u := Extract-Min(Q);S := S {u};for each v Adj[u] do

Relax(u, v, w)od

od

Initialize(G, s);S := ;Q := V[G];while Q do

u := Extract-Min(Q);S := S {u};for each v Adj[u] do

Relax(u, v, w)od

od

Page 71: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

memset(v,0,sizeof(v));memset(f,-1,sizeof(f));for(int i=0;i<n;i++) d[i] = INF;d[0] = 0;for(int i=0;i<n;i++){ int x, m = INF; for(int y=0;y<n;y++) if(!v[y] && d[y]<=m) m = d[x=y]; v[x] = 1; for(int y=0;y<n;y++) if(d[y]<d[x]+w[x][y]) { d[y]=d[x]+w[x][y]; f[y]=x; }}

v1 v2

v6 v7

v3 v4 v5

2

4

2

1 3 10

2

58 4 6

1

0v1

d f

v2

v3

v4

v5

v6

v7

0

0

0

0

0

0

0

2 v1

1 v1

3 v4

3 v4

9 v4

5 v4

8 v36 v7

Dijkstra Example

Page 72: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0

s

u v

x y

10

1

9

2

4 6

5

2 3

7

Page 73: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0

5

10

s

u v

x y

10

1

9

2

4 6

5

2 3

7

Page 74: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0

75

148

s

u v

x y

10

1

9

2

4 6

5

2 3

7

Page 75: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0

75

138

s

u v

x y

10

1

9

2

4 6

5

2 3

7

Page 76: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0

75

98

s

u v

x y

10

1

9

2

4 6

5

2 3

7

Page 77: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Example

0

75

98

s

u v

x y

10

1

9

2

4 6

5

2 3

7

Page 78: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

CorrectnessTheorem 24.6: Upon termination, d[u] = δ(s, u) for all u in V(assuming non-negative weights).

Theorem 24.6: Upon termination, d[u] = δ(s, u) for all u in V(assuming non-negative weights).

Proof:

By Lemma 24.11, once d[u] = δ(s, u) holds, it continues to hold.

We prove: For each u in V, d[u] = (s, u) when u is inserted in S.

Suppose not. Let u be the first vertex such that d[u] (s, u) wheninserted in S.

Note that d[s] = (s, s) = 0 when s is inserted, so u s.

S just before u is inserted (in fact, s S).

Page 79: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Proof (Continued)Note that there exists a path from s to u, for otherwise d[u] = (s, u) = by Corollary 24.12.

there exists a SP from s to u. SP looks like this:

x

s

y

u

S

p1

p2

Page 80: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Proof (Continued)Claim: d[y] = (s, y) when u is inserted into S.

We had d[x] = (s, x) when x was inserted into S.

Edge (x, y) was relaxed at that time.

By Lemma 24.14, this implies the claim.

Now, we have: d[y] = (s, y) , by Claim. (s, u) , nonnegative edge weights. d[u] , by Lemma 24.11.

Because u was added to S before y, d[u] d[y].

Thus, d[y] = (s, y) = (s, u) = d[u].

Contradiction.

Page 81: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

Complexity

Running time is

O(V2) using linear array for priority queue.

O((V + E) lg V) using binary heap.

O(V lg V + E) using Fibonacci heap.

(See Introduction to Algorithms.)

Page 82: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

All-Pairs Shortest Path Notice that finding the shortest path between a

pair of vertices (s, t) in worst case requires first finding the shortest path from s to all other vertices in the graph.

Many applications, such as finding the center or diameter of a graph, require finding the shortest path between all pairs of vertices.

We can run Dijkstra’s algorithm n times (once from each possible start vertex) to solve all-pairs shortest path problem in O(n3). Can we do better?

Page 83: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

All-Pairs Shortest Path The Floyd-Warshall algorithm starts by

numbering the vertices of the graph from 1 to n. Define W[i,j]k to be the length of the shortest path from i to j using only vertices numbered from 1,2,…,k as possible intermediate vertices.

When k=0, we are allowed no intermediate vertices, so the only allowed paths are the original edges. Thus the initial all-pairs shortest-path matrix consists of the initial adjacency matrix.

Page 84: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

All-Pairs Shortest Path We will perform n iterations, where the kth

iteration allows only the first k vertices as possible intermediate steps on the path between each pair of vertices x and y.

At each iteration, we allow a richer set of possible shortest path by adding a new vertex as a possible intermediary. Allowing the kth vertex as a stop helps only if there is a short path that goes through k, sow[i,j]k =

min(w[i,j]k-1 , w[i,k]k-1 + w[k,j]k-1 )

Page 85: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

86

Floyd-Warshall Algorithm

for (i =1; i<=n; i++)for (j =1; j<=n; j++)

d[i][i] = (i==j ? 0 : INF);for (k =1; k<=n; k++)for (i =1; i<=n; i++)for (j =1; j<=n; j++) { if (d[i][j] < d[i][k] + d[k][j]) d[i][j]=d[i][k] + d[k][j];}

Page 86: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

87

例题 Sicily 1031 Campus

每对顶点间的最短路径, floyed-warshall 算法 题目的点是用字符串给出的,可用一个 map

把点转成数字:int tot = 0;std::map<string, int> places;if (places.find(s) == places.end()) places[s] = tot++;v = places[s];

Page 87: Weighted Graph Algorithms. Contents 最小生成树 Prim 算法 并查集 Kruskal 算法 最短路问题 Dijkstra 算法 Bellman-Ford 算法 Floyd 算法 网络流初步 最大流问题

例题 电话圈( Calling Circles, ACM/ICPC World Finals 1996, UVa247) 如果两个人互相打电话(直接或间接),则说他们在同一

个电话圈。例如, a 打给 b, b 打给 c, c 打给 d, d 打给 a, 则这 4 个人在同一个圈里;如果 e 打给 f 但 f 不打给 e, 则不能推出 e 和 f 在同一个电话圈里。输入 n(n<=25) 个人的 m 次电话,找出所有电话圈。人名包含字母,不超过25 个字符,且不重复。

分析:首先用 floyd 求出传递闭包,即 g[i][j] 表示 i 是否直接或者间接给 j 打过电话,则当且仅当 g[i][j] = g[j][i] = 1 时,二者出于同一个电话圈。构造一个新图,在“在一个电话圈里”的两个人之间连一条边,然后依次输出各个连通分量的所有人即可。