To represent weighted edges using adjacency matrices and adjacency lists ( 25.2).

Similar documents
Weighted Graphs and Applications. CSE260, Computer Science B: Honors Stony Brook University

To model real-world problems using graphs and explain the Seven Bridges of Königsberg problem

Chapter 28 Graphs and Applications. Objectives

CSE 100 Minimum Spanning Trees Prim s and Kruskal

Chapter 28. Graphs and Applications. Part1. Non-weighted Graphs

SELF-BALANCING SEARCH TREES. Chapter 11

2. True or false: even though BFS and DFS have the same space complexity, they do not always have the same worst case asymptotic time complexity.

Konigsberg Bridge Problem

Graph Traversals. CS200 - Graphs 1

1 Copyright 2012 by Pearson Education, Inc. All Rights Reserved.

CSE 100: GRAPH ALGORITHMS

CS 310 Advanced Data Structures and Algorithms

GRAPHS AND APPLICATIONS

Graphs. directed and undirected graphs weighted graphs adjacency matrices. abstract data type adjacency list adjacency matrix

Graphs ADT and Traversing

CSE 100: GRAPH ALGORITHMS

CHAPTER 13 GRAPH ALGORITHMS

22 Elementary Graph Algorithms. There are two standard ways to represent a

10/31/18. About A6, Prelim 2. Spanning Trees, greedy algorithms. Facts about trees. Undirected trees

Spanning Trees, greedy algorithms. Lecture 20 CS2110 Fall 2018

Spanning Trees, greedy algorithms. Lecture 22 CS2110 Fall 2017

Undirected Graphs. Hwansoo Han

tree follows. Game Trees

18: GRAPH DATA STRUCTURES. Introduction

problem statement Prim s algorithm a multiple key map representation for a tree code for Prim s algorithm

CSE 100: GRAPH SEARCH

Spanning Trees 4/19/17. Prelim 2, assignments. Undirected trees

Spanning Trees. Lecture 22 CS2110 Spring 2017

Pred 8 1. Dist. Pred

Engineering Software Development in Java

Chapter 9 Graph Algorithms

Minimum-Spanning-Tree problem. Minimum Spanning Trees (Forests) Minimum-Spanning-Tree problem

11/22/2016. Chapter 9 Graph Algorithms. Introduction. Definitions. Definitions. Definitions. Definitions

DHANALAKSHMI COLLEGE OF ENGINEERING, CHENNAI. Department of Computer Science and Engineering CS6301 PROGRAMMING DATA STRUCTURES II

Lecture 10. Graphs Vertices, edges, paths, cycles Sparse and dense graphs Representations: adjacency matrices and adjacency lists Implementation notes

Homework Assignment #3 Graph

CS350: Data Structures Dijkstra s Shortest Path Alg.

Algorithm Design (8) Graph Algorithms 1/2

In this chapter, we consider some of the interesting problems for which the greedy technique works, but we start with few simple examples.

Graphs Chapter 24. Instructor: Scott Kristjanson CMPT 125/125 SFU Burnaby, Fall 2013

Graphs Introduction and Depth first algorithm

ECE 242 HOMEWORK 5. In the figure below, one can go from node B to A but not from A to B.

Week 12: Minimum Spanning trees and Shortest Paths

22 Elementary Graph Algorithms. There are two standard ways to represent a

Tutorial. Question There are no forward edges. 4. For each back edge u, v, we have 0 d[v] d[u].

Shortest Path Problem

Graphs & Digraphs Tuesday, November 06, 2007

Weighted Graph Algorithms Presented by Jason Yuan

UNIT III TREES. A tree is a non-linear data structure that is used to represents hierarchical relationships between individual data items.

Graph Algorithms. Chapter 22. CPTR 430 Algorithms Graph Algorithms 1

Dijkstra s algorithm for shortest paths when no edges have negative weight.


Minimum Spanning Trees

L22-23: Graph Algorithms

Chapter 14. Graphs Pearson Addison-Wesley. All rights reserved 14 A-1

UNIT Name the different ways of representing a graph? a.adjacencymatrix b. Adjacency list

Decreasing a key FIB-HEAP-DECREASE-KEY(,, ) 3.. NIL. 2. error new key is greater than current key 6. CASCADING-CUT(, )

Undirected Graphs. DSA - lecture 6 - T.U.Cluj-Napoca - M. Joldos 1

CS302 - Data Structures using C++

Data Structures Brett Bernstein

The Shortest Path Problem

Shortest Path Algorithms

Chapter 9. Priority Queue

Homework 6 Solutions CS330 Discrete Structures, Fall 2017

Week 11: Minimum Spanning trees

CSE100 Practice Final Exam Section C Fall 2015: Dec 10 th, Problem Topic Points Possible Points Earned Grader

Shortest Paths. CSE 373 Data Structures Lecture 21

COMP 182: Algorithmic Thinking Prim and Dijkstra: Efficiency and Correctness

All Shortest Paths. Questions from exercises and exams

CS302 - Data Structures using C++

Chapter 9. Greedy Technique. Copyright 2007 Pearson Addison-Wesley. All rights reserved.

An undirected graph G can be represented by G = (V, E), where

CSE 431/531: Analysis of Algorithms. Greedy Algorithms. Lecturer: Shi Li. Department of Computer Science and Engineering University at Buffalo

UNIT 3. Greedy Method. Design and Analysis of Algorithms GENERAL METHOD

Graphs. Tessema M. Mengistu Department of Computer Science Southern Illinois University Carbondale Room - Faner 3131

Trees, Heaps, and Priority Queues

SPANNING TREES. Lecture 21 CS2110 Spring 2016

CS490: Problem Solving in Computer Science Lecture 6: Introductory Graph Theory

CS 146 Spring 2017 Homework 4 Sections 5 and 6. The homework assignment is available at:

CSC 8301 Design & Analysis of Algorithms: Warshall s, Floyd s, and Prim s algorithms

SHORTEST PATHS. Weighted Digraphs. Shortest paths. Shortest Paths BOS ORD JFK SFO LAX DFW MIA

CSC Intro to Intelligent Robotics, Spring Graphs

CS/COE 1501 cs.pitt.edu/~bill/1501/ Graphs

Algorithms: Lecture 10. Chalmers University of Technology

Graphs Data Structures

Algorithm Design and Analysis

GRAPHS (Undirected) Graph: Set of objects with pairwise connections. Why study graph algorithms?

Lecture 4: Graph Algorithms

What is a minimal spanning tree (MST) and how to find one

implementing the breadth-first search algorithm implementing the depth-first search algorithm

Lecture 13. Reading: Weiss, Ch. 9, Ch 8 CSE 100, UCSD: LEC 13. Page 1 of 29

CS 561, Lecture 10. Jared Saia University of New Mexico

University of Illinois at Urbana-Champaign Department of Computer Science. Final Examination

Advanced Java Concepts Unit 9: Graph Exercises

University of Illinois at Urbana-Champaign Department of Computer Science. Final Examination

Lecture Notes. char myarray [ ] = {0, 0, 0, 0, 0 } ; The memory diagram associated with the array can be drawn like this

EECS 281 Homework 4 Key Fall 2004

Graphs. The ultimate data structure. graphs 1

Lecture 3: Graphs and flows

Graphs. What is a Graph? Computer Science S-111 Harvard University David G. Sullivan, Ph.D.

Transcription:

CHAPTER Weighted Graphs and Applications Objectives To represent weighted edges using adjacency matrices and adjacency lists (.). To model weighted graphs using the WeightedGraph class that extends the Graph class (.). To design and implement the algorithm for finding a minimum spanning tree (.4). To define the MST class that extends the Tree class (.4). To design and implement the algorithm for finding single-source shortest paths (.). To define the ShortestPathTree class that extends the Tree class (.). To solve the weighted nine tail problem using the shortest-path algorithm (.6).

. Introduction Key Point: A graph is a weighted graph if each edge is assigned a weight. Weighted graphs have many practical applications. Figure 4. assumes that the graph represents the number of flights among cities. You can apply the BFS to find the fewest number of flights between two cities. Assume that the edges represent the driving distances among the cities as shown in Figure.. How do you find the minimal total distances for connecting all cities? How do you find the shortest path between two cities? This chapter will address these questions. The former is known as the minimum spanning tree (MST) problem and the latter as the shortest path problem. Seattle (0) 07 097 00 Chicago () 77 9 Boston (6) 4 New York ( San Francisco () 67 0 Denver () 99 Kansas City (4) 60 66 64 Los Angeles () 4 496 7 Atlanta () Dallas (0) 9 0 66 Houston () 7 Miami (9) Figure. The graph models the distances among the cities. The preceding chapter introduced the concept of graphs. You learned how to represent edges using edge arrays, edge vectors, adjacency matrices, and adjacency lists, and how to model a graph using the Graph class. The chapter also introduced two important techniques for traversing graphs: depth-first search and breadth-first search, and applied traversal to solve practical problems. This chapter will introduce weighted graphs. You will learn the algorithm for finding a minimum spanning tree in.4 and the algorithm for finding shortest paths in.. PEDAGOGICAL NOTE Before we introduce the algorithms and applications for weighted graphs, it is helpful to get

acquainted with weighted graphs using the GUI interactive tool at www.cs.armstrong.edu/liang/animation/weightedgraphlearningtool.html. The tool allows you to enter vertices, specify edges and their weights, view the graph, and find an MST and all shortest paths from a single source, as shown in Figure.. Figure. You can use the tool to create a weighted graph with mouse gestures and show the MST and shortest paths.. Representing Weighted Graphs Key Point: Weighted edges can be stored in adjacency lists. There are two types of weighted graphs: vertex weighted and edge weighted. In a vertex-weighted graph, each vertex is assigned a weight. In an edge-weighted graph, each edge is assigned a weight. Of the two types, edge-weighted graphs have more applications. This chapter considers edge-weighted graphs. Weighted graphs can be represented in the same way as unweighted graphs, except that you have to represent the weights on the edges. As with unweighted graphs, the vertices in weighted graphs can be stored in an array. This section introduces three representations for the edges in weighted graphs.

.. Representing Weighted Edges: Edge Array Weighted edges can be represented using a two-dimensional array. For example, you can store all the edges in the graph in Figure. using the following array: int edges[][] = { {0,, }, {0,, }, {, 0, }, {,, 7}, {,, }, {,, 7}, {,, 4}, {, 4, }, {, 0, }, {,, }, {,, 4}, {, 4, 6}, {4,, }, {4,, 6} }; 7 4 6 0 4 Figure. Each edge is assigned a weight on an edge-weighted graph. NOTE For simplicity, we assume that the weights are integers... Weighted Adjacency Lists Another way to represent the edges is to define edges as objects. The Edge class was defined to represent edges in unweighted graphs. For weighted edges, we define the WeightedEdge class as shown in Listing.. Listing. WeightedEdge.cpp #ifndef WEIGHTEDEDGE_H #define WEIGHTEDEDGE_H 4 #include "Edge.h" 6 class WeightedEdge : public Edge 4

7 { public: 9 double weight; // The weight on edge (u, v) 0 // Create a weighted edge on (u, v) WeightedEdge(int u, int v, double weight): Edge(u, v) { 4 this->weight = weight; } 6 7 // Compare edges based on weights bool operator<(const WeightedEdge& edge) const 9 { 0 return (*this).weight < edge.weight; } bool operator<=(const WeightedEdge& edge) const 4 { return (*this).weight <= edge.weight; 6 } 7 bool operator>(const WeightedEdge& edge) const 9 { 0 return (*this).weight > edge.weight; } bool operator>=(const WeightedEdge& edge) const 4 { return (*this).weight >= edge.weight; 6 } 7 bool operator==(const WeightedEdge& edge) const 9 { 40 return (*this).weight == edge.weight; 4 } 4 4 bool operator!=(const WeightedEdge& edge) const 44 { 4 return (*this).weight!= edge.weight; 46 } 47 }; 4 #endif The Edge class, defined in Listing 4., represents an edge from vertex u to v. WeightedEdge extends Edge with a new property weight. To create a WeightedEdge object, use WeighedEdge(i, j, w), where w is the weight on edge (i, j). Often you need to compare the weights of the edges. For this reason, we define the operator functions (<, <=, ==,!=, >, >=) in the WeightedEdge class.

For unweighted graphs, we use adjacency edge lists to represent edges. For weighted graphs, we still use adjacency edge lists. Since WeightedEdge is derived from Edge. The adjacency edge list for unweighted graphs can be used for weighted graphs. For example, the adjacency edge lists for the vertices in the graph in Figure. can be represented as follows: vector<vector<edge*>> neighbors; for (unsigned i = 0; i < numberofvertices; i++) { neighbors.push_back(vector<edge*>()); } neighbors[0].push_back(new WeightedEdge(0,, )); neighbors[0].push_back(new WeightedEdge(0,, ));... wneighbors[0] wneighbors[] wneighbors[] wneighbors[] wneighbors[4] WeightedEdge(0,, ) WeightedEdge(0,, ) WeightedEdge(, 0, ) WeightedEdge(,, ) WeightedEdge(,, 7) WeightedEdge(,, 4) WeightedEdge(, 4, ) WeightedEdge(,, 7) WeightedEdge(,, ) WeightedEdge(,, 4) WeightedEdge(, 4, 6) WeightedEdge(, 0, ) WeightedEdge(4,, ) WeightedEdge(4,, 6) Check point. For the code WeightedEdge edge(,,.), what is edge.u, edge.v, and edge.weight?. What is the output of the following code? vector<weightededge> list; list.push_back(weightededge(,,.)); list.push_back(weightededge(,,.)); list.push_back(weightededge(4,, 4.)); cout << max_element(list.begin(), list.end())->weight << endl;. The WeightedGraph Class Key Point: The WeightedGraph class extends Graph. The preceding chapter designed the Graph class for modeling graphs. Following this pattern, we design WeightedGraph as a subclass of Graph, as shown in Figure.4. 6

Graph<V> Defined in Figure 4.7. WeightedGraph<V> +WeightedGraph() +WeightedGraph(vertices: vector<v>&, edges: vector<weightededge>&) +WeightedGraph(numberOfVertices: int, edges: vector<weightededge>&) +printweightededges(): void const +getminimumspanningtree(): MST const +getminimumspanningtree(v: int): MST const +getshortestpath(v: int): ShortestPathTree const +addedges(u: int, v: int, weigh t: double): b ool Constructs an empty WeightedGraph. Constructs a Wei ghtedgraph wit h the speci fi ed verti ces and edges in vectors. Constructs a WeightedGraph with vertices 0,,, n, and edges in a vector. Displays all edges and weights. Returns a min imum spanning tree starting from vertex 0. Returns a min imum spanning tree starting from vertex v. Returns all single-source shortes t paths. Adds a wei ghted edge t o the grap h and throws an invalid_argument if u, v, or w is invalid. Return s false if (u, v) is already in the graph. Figure.4 WeightedGraph extends Graph. WeightedGraph simply extends Graph. WeightedGraph inherits all functions from Graph and also introduces the new functions for obtaining minimum spanning trees and for finding single-source all shortest paths. Minimum spanning trees and shortest paths will be introduced in.4 and., respectively. The class contains three constructors. The first is a no-arg constructor to create an empty graph. The second constructs a WeightedGraph with the specified vertices and edges in vectors. The third constructs a WeightedGraph with vertices 0,,..., n- and an edge vector. The printweightededges function displays all edges for each vertex. Listing. implements WeightedGraph. Listing. WeightedGraph.h #ifndef WEIGHTEDGRAPH_H #define WEIGHTEDGRAPH_H 4 #include "Graph.h" #include "WeightedEdge.h" // Defined in Listing. 6 #include "MST.h" // Defined in Listing. 7 #include "ShortestPathTree.h" // Defined in Listing. 9 template<typename V> 0 class WeightedGraph : public Graph<V> { public: 7

// Construct an empty graph 4 WeightedGraph(); 6 // Construct a graph from vertices and edges objects 7 WeightedGraph(vector<V>& vertices, vector<weightededge>& edges); 9 // Construct a graph with vertices 0,,..., n- and 0 // edges in a vector WeightedGraph(int numberofvertices, vector<weightededge>& edges); // Print all edges in the weighted tree 4 void WeightedGraph<V>::printWeightedEdges(); 6 // Add a weighted edge 7 bool addedge(int u, int v, double w); 9 // Get a minimum spanning tree rooted at vertex 0 0 MST getminimumspanningtree(); // Get a minimum spanning tree rooted at a specified vertex MST getminimumspanningtree(int startingvertex); 4 // Find single-source shortest paths 6 ShortestPathTree getshortestpath(int sourcevertex); 7 }; 9 const int INFINITY = 474647; 40 4 template<typename V> 4 WeightedGraph<V>::WeightedGraph() 4 { 44 } 4 46 template<typename V> 47 WeightedGraph<V>::WeightedGraph(vector<V>& vertices, 4 vector<weightededge>& edges) 49 { 0 // Add vertices to the graph for (unsigned i = 0; i < vertices.size(); i++) { addvertex(vertices[i]); 4 } 6 // Add edges to the graph 7 for (unsigned i = 0; i < edges.size(); i++) { 9 addedge(edges[i].u, edges[i].v, edges[i].weight); 60 } 6 } 6 6 template<typename V> 64 WeightedGraph<V>::WeightedGraph(int numberofvertices, 6 vector<weightededge>& edges) 66 { 67 // Add vertices to the graph 6 for (int i = 0; i < numberofvertices; i++) 69 addvertex(i); // vertices is {0,,,..., n-} 70 7 // Add edges to the graph

7 for (unsigned i = 0; i < edges.size(); i++) 7 { 74 addedge(edges[i].u, edges[i].v, edges[i].weight); 7 } 76 } 77 7 template<typename V> 79 void WeightedGraph<V>::printWeightedEdges() 0 { for (int i = 0; i < getsize(); i++) { // Display all edges adjacent to vertex with index i 4 cout << "Vertex " << getvertex(i) << "(" << i << "): "; 6 // Display all weighted edges 7 for (Edge* e: neighbors[i]) { 9 cout << "(" << e->u << ", " << e->v << ", " 90 << static_cast<weightededge*>(e)->weight << ") "; 9 } 9 cout << endl; 9 } 94 } 9 96 template<typename V> 97 bool WeightedGraph<V>::addEdge(int u, int v, double w) 9 { 99 return createedge(new WeightedEdge(u, v, w)); 00 } 0 0 template<typename V> 0 MST WeightedGraph<V>::getMinimumSpanningTree() 04 { 0 return getminimumspanningtree(0); 06 } 07 0 template<typename V> 09 MST WeightedGraph<V>::getMinimumSpanningTree(int startingvertex) 0 { vector<int> T; // T contains the vertices in the tree vector<int> parent(getsize()); // Parent of a verte 4 parent[startingvertex] = -; // startingvertex is the root double totalweight = 0; // Total weight of the tree thus far 6 7 // cost[v] stores the cost by adding v to the tree vector<double> cost(getsize()); 9 for (unsigned i = 0; i < cost.size(); i++) 0 { cost[i] = INFINITY; // Initial cost set to infinity } cost[startingvertex] = 0; // Cost of source is 0 4 // Expand T 6 while (T.size() < getsize()) 7 { // Find smallest cost v in V - T 9 int u = -; // Vertex to be determined 0 double currentmincost = INFINITY; 9

for (int i = 0; i < getsize(); i++) { if (find(t.begin(), T.end(), i)== T.end() 4 && cost[i] < currentmincost) { 6 currentmincost = cost[i]; 7 u = i; } 9 } 40 4 T.push_back(u); // Add a new vertex to T 4 totalweight += cost[u]; // Add cost[u] to the tree 4 44 // Adjust cost[v] for v that is adjacent to u and v in V - T 4 for (Edge* e: neighbors[u]) 46 { 47 if (find(t.begin(), T.end(), e->v) == T.end() 4 && cost[e->v] > static_cast<weightededge*>(e)->weight) 49 { 0 cost[e->v] = static_cast<weightededge*>(e)->weight; parent[e->v] = u; } } 4 } // End of while 6 return MST(startingVertex, parent, T, totalweight); 7 } 9 template<typename V> 60 ShortestPathTree WeightedGraph<V>::getShortestPath(int sourcevertex) 6 { 6 // T stores the vertices whose path found so far 6 vector<int> T; 64 6 // parent[v] stores the previous vertex of v in the path 66 vector<int> parent(getsize()); 67 parent[sourcevertex] = -; // The parent of source is set to - 6 69 // cost[v] stores the cost of the path from v to the source 70 vector<double> cost(getsize()); 7 for (unsigned i = 0; i < cost.size(); i++) 7 { 7 cost[i] = INFINITY; // Initial cost set to infinity 74 } 7 cost[sourcevertex] = 0; // Cost of source is 0 76 77 // Expand T 7 while (T.size() < getsize()) 79 { 0 // Find smallest cost v in V - T int u = -; // Vertex to be determined double currentmincost = INFINITY; for (int i = 0; i < getsize(); i++) 4 { if (find(t.begin(), T.end(), i)== T.end() 6 && cost[i] < currentmincost) 7 { currentmincost = cost[i]; 0

9 u = i; 90 } 9 } 9 9 if (u == -) break; 94 9 T.push_back(u); // Add a new vertex to T 96 97 // Adjust cost[v] for v that is adjacent to u and v in V - T 9 for (Edge* e: neighbors[u]) 99 { 00 if (find(t.begin(), T.end(), e->v) == T.end() && 0 cost[e->v] > cost[u] + static_cast<weightededge*>(e)- >weight) 0 { 0 cost[e->v] = cost[u] + static_cast<weightededge*>(e)- >weight; 04 parent[e->v] = u; 0 } 06 } 07 } // End of while 0 09 // Create a ShortestPathTree 0 return ShortestPathTree(sourceVertex, parent, T, cost); } #endif WeightedGraph is derived from Graph (line 0). The properties vertices and neighbors are defined as protected in the parent class Graph, so they can be accessed in the child class WeightedGraph. When a WeightedGraph is constructed, its vertices and adjacency edge lists are created by invoking the addvertex function (lines 6, 7) and the addedge function (lines 6, 77). The addvertex function is defined the Graph class in Listing 4.. The addedge function invokes the createedge function to add a weighted edge to the graph (lines 96-00). The createedge function is defined as protected in Listing 4. Graph.h. This function checks whether the edge is valid and throws an invalid_argument exception if the edge is invalid. Listing. gives a test program that creates a graph for the one in Figure. and another graph for the one in Figure.. Listing. TestWeightedGraph.cpp #include <iostream> #include <string> #include <vector> 4 #include "WeightedGraph.h" #include "WeightedEdge.h" 6 using namespace std; 7 int main() 9 { 0 // Vertices for graph in Figure. string vertices[] = {"Seattle", "San Francisco", "Los Angeles", "Denver", "Kansas City", "Chicago", "Boston", "New York",

"Atlanta", "Miami", "Dallas", "Houston"}; 4 // Edge array for graph in Figure. 6 int edges[][] = { 7 {0,, 07}, {0,, }, {0,, 097}, {, 0, 07}, {,, }, {,, 67}, 9 {,, }, {,, 0}, {, 4, 66}, {, 0, 4}, 0 {, 0, }, {,, 67}, {,, 0}, {, 4, 99}, {,, 00}, {4,, 66}, {4,, 99}, {4,, }, {4, 7, 60}, {4,, 64}, {4, 0, 496}, 4 {, 0, 097}, {,, 00}, {, 4, }, {, 6, 9}, {, 7, 77}, 6 {6,, 9}, {6, 7, 4}, 7 {7, 4, 60}, {7,, 77}, {7, 6, 4}, {7,, }, {, 4, 64}, {, 7, }, {, 9, 66}, 9 {, 0, 7}, {,, 0}, 0 {9,, 66}, {9,, 7}, {0,, 4}, {0, 4, 496}, {0,, 7}, {0,, 9}, {,, 0}, {, 9, 7}, {, 0, 9} }; 4 // undirected edges in Figure. 6 const int NUMBER_OF_EDGES = 46; 7 // Create a vector for vertices 9 vector<string> vectorofvertices(); 40 copy(vertices, vertices +, vectorofvertices.begin()); 4 4 // Create a vector for edges 4 vector<weightededge> edgevector; 44 for (int i = 0; i < NUMBER_OF_EDGES; i++) 4 edgevector.push_back(weightededge(edges[i][0], 46 edges[i][], edges[i][])); 47 4 WeightedGraph<string> graph(vectorofvertices, edgevector); 49 cout << "The number of vertices in graph: " << graph.getsize(); 0 cout << "\nthe vertex with index is " << graph.getvertex(); cout << "\nthe index for Miami is " << graph.getindex("miami"); cout << "\nthe edges for graph: " << endl; 4 graph.printweightededges(); 6 // Create a graph for Figure. 7 int edges[][] = { 9 {0,, }, {0,, }, 60 {, 0, }, {,, 7}, {,, }, 6 {,, 7}, {,, 4}, {, 4, }, 6 {, 0, }, {,, }, {,, 4}, {, 4, 6}, 6 {4,, }, {4,, 6} 64 }; // 4 edges in Figure. 6 66 // 7 undirected edges in Figure. 67 const int NUMBER_OF_EDGES = 4; 6 69 vector<weightededge> edgevector; 70 for (int i = 0; i < NUMBER_OF_EDGES; i++) 7 edgevector.push_back(weightededge(edges[i][0],

7 edges[i][], edges[i][])); 7 74 WeightedGraph<int> graph(, edgevector); // vertices in graph 7 76 cout << "The number of vertices in graph: " << graph.getsize(); 77 cout << "\nthe edges for graph: " << endl; 7 graph.printweightededges(); 79 0 return 0; } Sample output The number of vertices in graph: The vertex with index is San Francisco The index for Miami is 9 The edges for graph: Vertex 0: (0,, 07) (0,, ) (0,, 097) Vertex : (,, ) (, 0, 07) (,, 67) Vertex : (,, ) (,, 0) (, 0, 4) (, 4, 66) Vertex : (, 4, 99) (,, 00) (,, 0) (,, 67) (, 0, ) Vertex 4: (4, 0, 496) (4,, ) (4,, 99) (4,, 64) (4, 7, 60) (4,, 66) Vertex : (, 4, ) (, 7, 77) (, 6, 9) (,, 00) (, 0, 097) Vertex 6: (6, 7, 4) (6,, 9) Vertex 7: (7, 6, 4) (7,, 77) (7,, ) (7, 4, 60) Vertex : (, 9, 66) (, 0, 7) (,, 0) (, 4, 64) (, 7, ) Vertex 9: (9,, 66) (9,, 7) Vertex 0: (0,, 9) (0, 4, 496) (0,, 7) (0,, 4) Vertex : (, 0, 9) (,, 0) (, 9, 7) The number of vertices in graph: The edges for graph: Vertex 0: (0,, ) (0,, ) Vertex : (, 0, ) (,, ) (,, 7) Vertex : (,, 4) (, 4, ) (,, 7) Vertex : (,, ) (,, 4) (, 4, 6) (, 0, ) Vertex 4: (4,, ) (4,, 6) The program creates graph for the graph in Figure 4. in lines 46. The vertices for graph are defined in lines. The edges for graph are defined in lines 6. The edges are represented using a two-dimensional array. For each row i in the array, edges[i][0] and edges[i][] indicate that there is an edge from vertex edges[i][0] to vertex edges[i][] and the weight for the edge is edges[i][]. For example, the first row {0,, 07} represents the edge from vertex 0 (edges[0][0]) to vertex (edges[0][]) with weight 07 (edges[0][]). The row {0,, 097} represents the edge from vertex 0 (edges[][0]) to vertex (edges[][]) with weight

097 (edges[][]). To create a WeightedGraph, you have to obtain a vector of WeightedEdge (lines 4 44). Line invokes the printweightededges() function on graph to display all edges in graph. The program creates a WeightedGraph graph for the graph in Figure. in lines 7. Line 7 invokes the printweightededges() function on graph to display all edges in graph. Check point. What is the output of the following code? vector<weightededge> list; list.push_back(weightededge(,,.)); list.push_back(weightededge(, 6, 6.)); list.push_back(weightededge(, 7,.)); cout << list[0].weight << endl; q.pop(); cout << list[].weight << endl; q.pop(); cout << list[].weight << endl;.4 What is the output of the following code? priority_queue<weightededge, vector<weightededge>, greater<weightededge>> q; q.push(weightededge(,,.)); q.push(weightededge(, 6, 6.)); q.push(weightededge(, 7,.)); cout << q.top().weight << endl; q.pop(); cout << q.top().weight << endl; q.pop(); cout << q.top().weight << endl;. What is wrong in the following code? Fix it and show the printout. 4

vector<vector<weightededge>> neighbors; neighbors[0].push_back(weightededge(0,,.)); neighbors[0].push_back(weightededge(0, 6, 6.)); neighbors[0].push_back(weightededge(0, 7,.)); neighbors[].push_back(weightededge(, 0,.)); neighbors[].push_back(weightededge(,,.)); neighbors[].push_back(weightededge(,, 9.)); cout << neighbors[0][0] << endl;.4 Minimum Spanning Trees Key Point: A minimum spanning tree of a graph is a spanning tree with the minimum total weights. A graph may have many spanning trees. Suppose that the edges are weighted. A minimum spanning tree is a spanning tree with the minimum total weights. For example, the trees in Figures.b,.c,.d are spanning trees for the graph in Figure.a. The trees in Figures.c and.d are minimum spanning trees. 0 0 6 7 0 7 7 7 7 (a) (b) 6 7 6 7 7 7 (c) (d)

Figure. The tree in (c) and (d) are minimum spanning trees of the graph in (a). The problem of finding a minimum spanning tree has many applications. Consider a company with branches in many cities. The company wants to lease telephone lines to connect all branches together. The phone company charges different amounts of money to connect different pairs of cities. There are many ways to connect all branches together. The cheapest way is to find a spanning tree with the minimum total rates..4. Minimum Spanning Tree Algorithms How do you find a minimum spanning tree? There are several well-known algorithms for doing so. This section introduces Prim s algorithm. Prim s algorithm starts with a spanning tree T that contains an arbitrary vertex. The algorithm expands the tree by adding a vertex with the smallest edge incident to a vertex already in the tree. The algorithm is described in Listing.4. Listing.4 Prim s Minimum Spanning Tree Algorithm Input: A connected undirected weighted G = (V, E) Output: MST (a minimum spanning tree) MST minimumspanningtree() { Let T be a set for the vertices in the spanning tree; 4 Set cost[v] = infinity for each vertex v; Pick an arbitrary vertex, say s and set cost[s] = 0 and parent[s] = -; 6 7 while (size of T < n) { 9 Find u not in T with the smallest cost[u]; 6

0 Add u to T; for (each v not in T and (u, v) in E) { if (cost[v] > w(u, v)) 4 cost[v] = w(u, v); parent[v] = u; } 6 } The algorithm starts by selecting an arbitrary vertex s and assign 0 to cost[s] (line ) and infinity to cost[v] for all other vertices (line 4). It then adds s into T during the first iteration of the while loop (lines 7-6). After s is added into T, adjust cost[v] for each v adjacent to s. cost[v] is the smallest weight among all v s edges that are adjacent to a vertex in T. If cost[v] is infinity, it indicates that v is not adjacent to any vertex in T at the moment. In each subsequent iteration of the while loop, the vertex u with the smallest cost[u] is picked and added into T (lines 9-0), as shown in Figure.6a. Afterwards, cost[v] is updated to w(u, v) and parent[v] to u for each v in V-T and v is adjacent to u if cost[v] > w(u, v) (lines -4), as shown in Figure.6b. Here, w(u, v) denotes the weight on edge (u, v). Figure.6 (a) Find a vertex u in V T with the smallest cost[u]. (b) Update cost[v] for v in V T and v is adjacent to u. V - T V - T T u v T v s v v s u v v T cont ai ns vertices i n the spanning tree V- T contai ns vertices currently not in the spanning tree. cost[v] stores the smallest edge weight to a vertex in T. T contains vertices in the spanning tree. V- T contai ns vertices currently not in the spanning tree. cost[v] stores the smallest edge weight to a vertex in T. (a) Before moving u to T (b) After moving u to T 7

Consider the graph in Figure.7a. Suppose the algorithm selects 0 and assigns cost[0] = 0 and parent[0] = -. The algorithm adds the vertices to T in this order:. Add vertex 0 to T and set cost[], parent[], cost[], and parent[], as shown in Figure.7b. Add vertex to T, since cost[] is the smallest. Update the cost and parent values for vertices, 6, and 4, as shown in Figure.7c.. cost[] and cost[6] are now the smallest in V-T. Pick either, say vertex. Add vertex to T. Update the cost and parent for the adjacent vertices of if applicable, as shown in Figure.7d. 4. Add vertex 6 to T, since cost[6] has the smallest weight among all edges adjacent to the vertices in T. Update the cost and parent for the adjacent vertices of 6 if applicable, as shown in Figure.7e.. Add vertex 4 to T, since cost[4] has the smallest weight among all edges adjacent to the vertices in T. Update the cost and parent for the adjacent vertices of 4 if applicable, as shown in Figure.7f. 6. Add vertex to T, since cost[] has the smallest weight among all edges adjacent to the vertices in T, as shown in Figure.7e. 7. Since is the only vertex in V-T, add vertex to T, as shown in Figure.7f. Figure.7 The adjacent vertices with the smallest weight are added successively to T. 0 9 0 7 6 cost 0 0 4 6 parent - T 4 0 4 6 (a)

0 cost 0 9 9 7 T 0 4 6 0 6 parent - 0 0 T 4 0 4 6 (b) 0 cost 0 9 7 T 0 4 6 0 6 parent - 0 T 4 0 4 6 (c) 0 T 9 0 7 6 cost 0 0 0 4 6 parent - 0 T 4 0 4 6 (d) 9

0 T 9 0 7 6 cost 0 0 0 4 6 parent - 6 0 T 4 0 4 6 (e) 0 T 9 0 7 6 cost 0 0 4 6 parent - 4 4 6 0 4 0 4 6 (e) 0 T 9 0 7 6 cost 0 0 4 6 parent - 4 4 6 0 4 0 4 6 (f) 0 T 9 0 7 6 cost 0 0 4 6 parent - 4 4 6 0 4 0 4 6 0

(g) NOTE: A minimum spanning tree is not unique. For example, both Figure.c and Figure.d are minimum spanning trees for the graph in Figure.7a. However, if the weights are distinct, the graph has a unique minimum spanning tree. NOTE: Assume that the graph is connected and undirected. If a graph is not connected or directed, the program may not work. You may modify the program to find a spanning forest for any undirected graph. The getminimumspanningtree(int v) function is defined in the WeightedGraph class. It returns an instance of the MST class. The MST class is defined as a child class of Tree, as shown in Figure.. The Tree class was defined in Listing 4.4. Listing. implements the MST class. Tree Defined in Figure 4.. MST -totalweight: double +MST() +MST(root: int, parent: vector<int>&, searchorders: vector<int>&, totalweight: double) +gettotalweight(): double Total weight of the tree. Constructs an empty MST. Constructs an MST with the specified root, parent vector, search order vector, and total weight for the tree. Returns the totalweight of the tree. Figure. The MST class extends the Tree class. Listing. MST.h #ifndef MST_H #define MST_H

4 #include "Tree.h" // Defined in Listing 4.4 6 class MST : public Tree 7 { public: 9 // Create an empty MST 0 MST() { } 4 // Construct a tree with root, parent, searchorders, // and total weight 6 MST(int root, vector<int>& parent, vector<int>& searchorders, 7 double totalweight) : Tree(root, parent, searchorders) { 9 this->totalweight = totalweight; 0 } // Return the total weight of the tree double gettotalweight() 4 { return totalweight; 6 } 7 private: 9 double totalweight; 0 }; #endif The getminimumspanningtree function was implemented in lines 7 in Listing.. The getminimumspanningtree() function picks vertex 0 as the starting vertex and invokes the getminimumspanningtree(0) function to return the MST starting from 0 (line 0). The getminimumspanningtree(startingvertex) function sets cost[startingvertex] to 0 (line 0) and cost[v] to infinity for all other vertices (lines 46-49). It then repeatedly finds the vertex with the smallest cost in V-T (lines 6-66) and adds it to T (lines 6. After a vertex u is added to T, the cost and parent for each vertex v in V-T adjacent to u may be adjusted (lines 7-). After a new vertex is added to T (line 9), totalweight is updated (line 69). Once all vertices are added to T, an instance of MST is created (line 4).

The MST class extends the Tree class. To create an instance of MST, pass root, parent, searchorders, and totalweight (lines 00). The data fields root, parent, and searchorders are defined in the Tree class. Since T is a vector, testing whether a vertex k is in T by invoking the STL find algorithm (line 6) takes O(n) time. The testing time can be reduced to O() by introducing an array, say isint, to track whether a vertex k is in T. Whenever a vertex k is added to T, set isint[k] to true. See Programming Exercise. for implementing the algorithm using isint. So, the total time for finding the vertex to be added into T is O( V ). Every time after a vertex u is added into T, the function updates cost[v] and parent[v] for each vertex v adjacent to u and for v in V-T. vertex v s cost and parent are updated if cost[v] > w(u, v). Each edge incident to u is examined only once. So the total time for examining the edges is O( E ). Therefore the time complexity of this implementation is O( V + E )=O( V ). Using priority queues, we can implement the algorithm in O( E log V ) time (see Programming Exercise.9), which is more efficient for sparse graphs. Listing.6 gives a test program that displays minimum spanning trees for the graph in Figure. and the graph in Figure., respectively. Listing.6 TestMinimumSpanningTree.cpp #include <iostream> #include <string> #include <vector> 4 #include "WeightedGraph.h" // Defined in Listing. #include "WeightedEdge.h" // Defined in Listing. 6 using namespace std; 7 // Print tree 9 template<typename T> 0 void printtree(tree& tree, vector<t>& vertices) { cout << "\nthe root is " << vertices[tree.getroot()]; cout << "\nthe edges are:"; 4 for (unsigned i = 0; i < vertices.size(); i++) { 6 if (tree.getparent(i)!= -) 7 cout << " (" << vertices[i] << ", " << vertices[tree.getparent(i)] << ")"; 9 } 0 cout << endl; }

int main() 4 { // Vertices for graph in Figure. 6 string vertices[] = {"Seattle", "San Francisco", "Los Angeles", 7 "Denver", "Kansas City", "Chicago", "Boston", "New York", "Atlanta", "Miami", "Dallas", "Houston"}; 9 0 // Edge array for graph in Figure. int edges[][] = { {0,, 07}, {0,, }, {0,, 097}, {, 0, 07}, {,, }, {,, 67}, 4 {,, }, {,, 0}, {, 4, 66}, {, 0, 4}, {, 0, }, {,, 67}, {,, 0}, {, 4, 99}, 6 {,, 00}, 7 {4,, 66}, {4,, 99}, {4,, }, {4, 7, 60}, {4,, 64}, {4, 0, 496}, 9 {, 0, 097}, {,, 00}, {, 4, }, 40 {, 6, 9}, {, 7, 77}, 4 {6,, 9}, {6, 7, 4}, 4 {7, 4, 60}, {7,, 77}, {7, 6, 4}, {7,, }, 4 {, 4, 64}, {, 7, }, {, 9, 66}, 44 {, 0, 7}, {,, 0}, 4 {9,, 66}, {9,, 7}, 46 {0,, 4}, {0, 4, 496}, {0,, 7}, {0,, 9}, 47 {,, 0}, {, 9, 7}, {, 0, 9} 4 }; 49 0 // undirected edges in Figure. const int NUMBER_OF_EDGES = 46; // Create a vector for vertices 4 vector<string> vectorofvertices(); copy(vertices, vertices +, vectorofvertices.begin()); 6 7 // Create a vector for edges vector<weightededge> edgevector; 9 for (int i = 0; i < NUMBER_OF_EDGES; i++) 60 edgevector.push_back(weightededge(edges[i][0], 6 edges[i][], edges[i][])); 6 6 WeightedGraph<string> graph(vectorofvertices, edgevector); 64 MST tree = graph.getminimumspanningtree(); 6 cout << "The spanning tree weight is " << tree.gettotalweight(); 66 printtree<string>(tree, graph.getvertices()); 67 6 // Create a graph for Figure. 69 int edges[][] = 70 { 7 {0,, }, {0,, }, 7 {, 0, }, {,, 7}, {,, }, 7 {,, 7}, {,, 4}, {, 4, }, 74 {, 0, }, {,, }, {,, 4}, {, 4, 6}, 7 {4,, }, {4,, 6} 76 }; // 4 edges in Figure. 77 7 // 7 undirected edges in Figure. 79 const int NUMBER_OF_EDGES = 4; 0 4

vector<weightededge> edgevector; for (int i = 0; i < NUMBER_OF_EDGES; i++) edgevector.push_back(weightededge(edges[i][0], 4 edges[i][], edges[i][])); 6 WeightedGraph<int> graph(, edgevector); // vertices in graph 7 MST tree = graph.getminimumspanningtree(); cout << "\nthe spanning tree weight is " << tree.gettotalweight(); 9 printtree<int>(tree, graph.getvertices()); 90 9 tree.printtree(); 9 9 return 0; 94 } Sample output The spanning tree weight is 6 The root is Seattle The edges are: (Seattle, San Francisco) (San Francisco, Los Angeles) (Los Angeles, Denver) (Denver, Kansas City) (Kansas City, Chicago) (New York, Boston) (Chicago, New York) (Dallas, Atlanta) (Atlanta, Miami) (Kansas City, Dallas) (Dallas, Houston) The spanning tree weight is 4 The root is 0 The edges are: (0, ) (, ) (, ) (, 4) The program creates a weighted graph for Figure 4. in line 60. It then invokes getminimumspanningtree() (line 6) to return a MST that represents a minimum spanning tree for the graph. Invoking gettotalweight() on the MST object returns the total weight of the minimum spanning tree. The printtree() function (lines 9 0) on the MST object displays the edges in the tree. Note that MST is a subclass of Tree. The graphical illustration of the minimum spanning tree is shown in Figure.9. The vertices are added to the tree in this order: Seattle, San Francisco, Los Angeles, Denver, Kansas City, Dallas, Houston, Chicago, New York, Boston, Atlanta, and Miami.

Seattle 07 San Francisco 67 0 097 Denver 66 00 99 4 Kansas City Chicago 7 64 60 77 9 Boston 9 4 New York Los Angeles 4 496 7 0 Atlanta 0 Dallas 9 6 66 Houston 7 Miami Figure.9 The edges in the minimum spanning tree for the cities are highlighted. Check point. Find a minimum spanning tree for the following graph..6 Is the minimum spanning tree unique if all edges have different weights?.7 If you use an adjacency matrix to represent weighted edges, what will be the time complexity for Prim s algorithm?. What happens to the getminimumspanningtree() function in WeightedGraph if the graph is not connected? Verify your answer by writing a test program that creates an unconnected graph and invokes the getminimumspanningtree() function. <end check point> 6

. Finding Shortest Paths <key point> The shortest path between two vertices is the path with the minimum total weights. <end key point> Given a graph with nonnegative weights on the edges, a well-known algorithm for finding a single-source shortest path was discovered by Edsger Dijkstra, a Dutch computer scientist. In order to find a shortest path from vertex s to vertex v, Dijkstra s algorithm finds the shortest path from s to all vertices. So Dijkstra s algorithm is known as a single-source shortest path algorithm. The algorithm uses cost[v] to store the cost of the shortest path from vertex v to the source vertex s. cost[s] is 0. Initially assign infinity to cost[v] for other vertices otherwise. Let V denote all vertices in the graph and T denote the set of the vertices whose costs are known. Initially, The algorithm repeatedly finds a vertex u in V T with the smallest cost[u] and moves u to T. Afterwards, adjust the cost and parent for each vertex v in V-T if v is adjacent to u and cost[v] > cost[u] + w(u, v). <key term>shortest path <key term>dijkstra s algorithm <key term>single-source shortest path The algorithm is described in Listing.7. Listing.7 Dijkstra s Single-Source Shortest-Path Algorithm Input: a graph G = (V, E) with non-negative weights and a source vertex s Output: a shortest path tree with the source vertex s as the root ShortestPathTree getshortestpath(s) { Let T be a set that contains the vertices whose 4 paths to s are known; Set cost[v] = infinity for all vertices; 6 Set cost[s] = 0 and parent[s] = -; 7 while (size of T < n) 9 { 0 Find u not in T with the smallest cost[u]; 7

Add u to T; for (each v not in T and (u, v) in E) { 4 if (cost[v] > cost[u] + w(u, v)) cost[v] = cost[u] + w(u, v); parent[v] = u; 6 } 7 } This algorithm is very similar to Prim s for finding a minimum spanning tree. Both algorithms divide the vertices into two sets: T and V - T. In the case of Prim s algorithm, set T contains the vertices that are already added to the tree. In the case of Dijkstra s, set T contains the vertices whose shortest paths to the source have been found. Both algorithms repeatedly find a vertex from V T and add it to T. In the case of Prim s algorithm, the vertex is adjacent to some vertex in the set with the minimum weight on the edge. In Dijkstra s algorithm, the vertex is adjacent to some vertex in the set with the minimum total cost to the source. The algorithm starts by setting cost[s] to 0 and parent[s] to - and cost[v] to infinity for all other vertices. We use the parent[i] to denote the parent of i in the path. For convenience, set the parent of the source node to -. The algorithm continuously adds a vertex (say u) from V T into T with smallest cost[u] (lines 0-), as shown in Figure.0a. After adding u to T, the algorithm updates cost[v] and parent[v] for each v not in T if (u, v) is in T and cost[v] > cost[u] + w(u, v)(lines -6). Figure.0 (a) Find a vertex u in V T with the smallest cost[u]. (b) Update cost[v] for v in V T and v is adjacent to u. V - T V - T T u v T v s v v s u v v T cont ai ns vertices whose shortest path to s are kn own. V- T contains vertices whose shortest path to s are not known yet. cost[v] stores the tentative shortest dis tance to s from v. T contains vertices whose shortest path to s are kn own. V- T contains vertices whose shortest path to s are not known yet. cost[v] stores the tentative shortest distance to s

(a) Before moving u to T (b) After moving u to T Let us illustrate Dijkstra s algorithm using the graph in Figure.0a. Suppose the source vertex is. Therefore, cost[] = 0 and parent[] = -, and the costs for all other vertices are initially, as shown in Figure.0b. Figure.0 The algorithm will find all shortest paths from source vertex. 9 0 6 4 cost 0 0 4 6 parent 7-0 4 0 4 6 (a) (b) Now T contains {}. Vertex is the one in V-T with the smallest cost, so add to T, as shown in Figure. and update the cost and parent for vertices in V-T and adjacent to if applicable. The cost and parent for vertices 0,,, and 6 are now updated, as shown in Figure.b. Figure. Now vertex is in set T. T 9 0 6 4 cost 0 0 9 0 4 6 parent 7-0 4 0 4 6 (a) (b) 9

Now T contains {}. Vertex is the one in V-T with the smallest cost, so add to T, as shown in Figure. and update the cost and parent for vertices in V-T and adjacent to. cost[0] is now updated to 6 and its parent is set to. Figure. Now vertices and are in set T. T 9 0 6 4 cost 6 0 0 9 0 4 6 parent 7-0 4 0 4 6 (a) (b) Now T contains {, }. Vertex 0 is the one in V-T with the smallest cost, so add 0 to T, as shown in Figure.4 and update the cost and parent for vertices in V-T and adjacent to 0 if applicable. cost[] is now updated to 0 and its parent is set to 0 and cost[6] is now updated to and its parent is set to 0. Figure.4 Now vertices {,, 0} are in set T. T 9 0 6 4 cost 6 0 0 0 0 4 6 parent 7-0 0 4 0 4 6 (a) (b) 0

Now T contains {,, 0}. Vertex 6 is the one in V-T with the smallest cost, so add 6 to T, as shown in Figure. and update the cost and parent for vertices in V-T and adjacent to 6 if applicable. Figure. Now vertices {,, 0, 6} are in set T. T 9 0 6 4 cost 6 0 0 0 0 4 6 parent 7-0 0 4 0 4 6 (a) (b) Now T contains {,, 0, 6}. Vertex or is is the one in V-T with the smallest cost. You may add either or into T. Let us add to T, as shown in Figure.6 and update the cost and parent for vertices in V-T and adjacent to if applicable. cost[4] is now updated to and its parent is set to. T 9 0 6 4 cost 6 0 0 0 0 4 6 parent 7-0 0 0 4 0 4 6 (a) (b) Figure.6 Now vertices {,, 0, 6, } are in set T.

Now T contains {,, 0, 6, }. Vertex is the one in V-T with the smallest cost, so add to T, as shown in Figure.7 and update the cost and parent for vertices in V-T and adjacent to if applicable. cost[4] is now updated to 0 and its parent is set to. T 9 0 6 4 cost 6 0 0 0 0 4 6 parent 7-0 0 0 4 0 4 6 (a) (b) Figure.7 Now vertices {,, 0, 6,, } are in set T. Now T contains {,, 0, 6,, }. Vertex 4 is the one in V-T with the smallest cost, so add 4 to T, as shown in Figure. and update the cost and parent for vertices in V-T and adjacent to 4 if applicable. T 9 0 6 4 cost 6 0 0 0 9 0 4 6 parent 7-0 0 4 0 4 6 (a) (b) Figure. Now vertices {,, 6, 0,,, 4} are in set T.

As you see, the algorithm essentially finds all shortest paths from a source vertex, which produces a tree rooted at the source vertex. We call this tree a single-source all-shortest-path tree (or simply a shortest-path tree). To model this tree, define a class named ShortestPathTree that extends the Tree class, as shown in Figure.9. Listing. implements the ShortestPathTree class Tree Defined in Figure 4.. ShortestPathTree -cost: vector<int> + ShortestPathTree() +ShortestPathTree(source: int, parent: vector<int>&, searchorders: vector<int>&, cost: vector<int>&) +getcost(v: int): int const cost[v] stores the cost for the path from the source to v. Constructs an empty Sh ortestpathtree. Constructs a shortest-path tree with the specified source, parent vector, search orders, and costs vector. Returns th e cost for the path from the source to vertex v. Figure.9 ShortestPathTree extends Tree. Listing. ShortestPathTree.h #ifndef SHORTESTPATHTREE_H #define SHORTESTPATHTREE_H 4 #include "Tree.h" // Defined in Listing 4.4 6 class ShortestPathTree : public Tree 7 { public: 9 // Create an empty ShortestPathTree 0 ShortestPathTree() { } 4 // Construct a tree with root, parent, searchorders, // and cost 6 ShortestPathTree(int root, vector<int>& parent, 7 vector<int>& searchorders, vector<double>& cost) : Tree(root, parent, searchorders) 9 { 0 this->cost = cost; } // Return the cost for the path from the source to vertex v. 4 double getcost(int v) { 6 return cost[v]; 7 } 9 private: 0 vector<double> cost; }; #endif

The getshortestpath(int sourcevertex) function was implemented in lines 60 0 in Listing., WeightedGraph.h. The function first sets cost[sourcevertex] to 0 (line 76) and cost[v] to infinity for all other vertices (lines 7-76). The parent array stores the parent for each vertex to enable us to identify the path from the source to all other vertices in the graph (line 67). The parent of the root is set to - (line 6). T is a set that stores the vertices whose path has been found (line 64). The function expands T by performing the following operations:. Find the vertex u with the smallest cost[u] (lines -9) and add it into T (line 96). If such a vertex is not found, the graph is not connected and the source vertex cannot reach all vertices in the graph (line 94).. After adding u in T, update cost[v] and parent[v] for each v adjacent to u in V-T if cost[v] > cost[u] + w(u, v) (lines 99-07). Once all reachable vertices from s are added to T, an instance of ShortestPathTree is created (line ). The ShortestPathTree class extends the Tree class. To create an instance of ShortestPathTree, pass sourcevertex, parent, searchorders, and cost (lines ). sourcevertex becomes the root in the tree. The data fields root, parent, and searchorders are defined in the Tree class. As discussed early in the getminimumspanningtree function, we can reduce the time to O() for testing whether a vertex k is in T by introducing an array, say isint, to track whether a vertex k is in T. Whenever a vertex k is added to T, set isint[k] to true. It takes O( V ) time to find a u with the smallest cost[u] using a linear search (lines -60). So, the total time for finding the vertex to be added into T is O( V ). Every time after a vertex u is added into T, the function updates cost[v] and parent[v] for each vertex v adjacent to u and for v in V-T. vertex v s cost and parent are updated if cost[v] > w(u, v). Each edge incident to u is examined only once. So the total time for examining the edges is O( E ). Therefore the time complexity of this implementation is O( V + E )=O( V ). Using 4

priority queues, we can implement the algorithm in O( E log V ) time (see Programming Exercise.0), which is more efficient for sparse graphs. Dijkstra s algorithm is a combination of a greedy algorithm and dynamic programming. It is a greedy algorithm in the sense that it always adds a new vertex that has the shortest distance to the source. It stores the shortest distance of each known vertex to the source and uses it later to avoid redundant computing, so Dijkstra s algorithm also uses dynamic programming. PEDAGOGICAL NOTE Go to www.cs.armstrong.edu/liang/animation/shortestpathanimation.html to use a GUI interactive program to find the shortest path between any two cities, as shown in Figure.0. Figure.0 The animation tool displays a shortest path between two cities. Listing.9 gives a test program that displays the shortest paths from Chicago to all other cities in Figure. and the shortest paths from vertex to all vertices for the graph in Figure.a, respectively.

Listing.9 TestShortestPath.cpp #include <iostream> #include <string> #include <vector> 4 #include "WeightedGraph.h" // Defined in Listing. #include "WeightedEdge.h" // Defined in Listing. 6 using namespace std; 7 // Print paths from all vertices to the source 9 template<typename T> 0 void printallpaths(shortestpathtree& tree, vector<t> vertices) { cout << "All shortest paths from " << vertices[tree.getroot()] << " are:" << endl; 4 for (unsigned i = 0; i < vertices.size(); i++) { 6 cout << "To " << vertices[i] << ": "; 7 // Print a path from i to the source 9 vector<int> path = tree.getpath(i); 0 for (int j = path.size() - ; j >= 0; j--) { cout << vertices[path[j]] << " "; } 4 cout << "(cost: " << tree.getcost(i) << ")" << endl; 6 } 7 } 9 int main() 0 { // Vertices for graph in Figure 4. string vertices[] = {"Seattle", "San Francisco", "Los Angeles", "Denver", "Kansas City", "Chicago", "Boston", "New York", 4 "Atlanta", "Miami", "Dallas", "Houston"}; 6 // Edge array for graph in Figure 4. 7 int edges[][] = { {0,, 07}, {0,, }, {0,, 097}, 9 {, 0, 07}, {,, }, {,, 67}, 40 {,, }, {,, 0}, {, 4, 66}, {, 0, 4}, 4 {, 0, }, {,, 67}, {,, 0}, {, 4, 99}, 4 {,, 00}, 4 {4,, 66}, {4,, 99}, {4,, }, {4, 7, 60}, 44 {4,, 64}, {4, 0, 496}, 4 {, 0, 097}, {,, 00}, {, 4, }, 46 {, 6, 9}, {, 7, 77}, 47 {6,, 9}, {6, 7, 4}, 4 {7, 4, 60}, {7,, 77}, {7, 6, 4}, {7,, }, 49 {, 4, 64}, {, 7, }, {, 9, 66}, 0 {, 0, 7}, {,, 0}, {9,, 66}, {9,, 7}, {0,, 4}, {0, 4, 496}, {0,, 7}, {0,, 9}, {,, 0}, {, 9, 7}, {, 0, 9} 4 }; 6 // undirected edges in Figure. 6

7 const int NUMBER_OF_EDGES = 46; 9 // Create a vector for vertices 60 vector<string> vectorofvertices(); 6 copy(vertices, vertices +, vectorofvertices.begin()); 6 6 // Create a vector for edges 64 vector<weightededge> edgevector; 6 for (int i = 0; i < NUMBER_OF_EDGES; i++) 66 edgevector.push_back(weightededge(edges[i][0], 67 edges[i][], edges[i][])); 6 69 WeightedGraph<string> graph(vectorofvertices, edgevector); 70 ShortestPathTree tree = graph.getshortestpath(); 7 printallpaths<string>(tree, graph.getvertices()); 7 7 // Create a graph for Figure. 74 int edges[][] = 7 { 76 {0,, }, {0,, }, 77 {, 0, }, {,, 7}, {,, }, 7 {,, 7}, {,, 4}, {, 4, }, 79 {, 0, }, {,, }, {,, 4}, {, 4, 6}, 0 {4,, }, {4,, 6} }; // 7 undirected edges in Figure. // 7 undirected edges in Figure. 4 const int NUMBER_OF_EDGES = 4; 6 vector<weightededge> edgevector; 7 for (int i = 0; i < NUMBER_OF_EDGES; i++) edgevector.push_back(weightededge(edges[i][0], 9 edges[i][], edges[i][])); 90 9 WeightedGraph<int> graph(, edgevector); // vertices in graph 9 ShortestPathTree tree = graph.getshortestpath(); 9 printallpaths<int>(tree, graph.getvertices()); 94 9 return 0; 96 } Sample output All shortest paths from Chicago are: To Seattle: Chicago Seattle (cost: 097) To San Francisco: Chicago Denver San Francisco (cost: 70) To Los Angeles: Chicago Denver Los Angeles (cost: 0) To Denver: Chicago Denver (cost: 00) To Kansas City: Chicago Kansas City (cost: ) To Chicago: Chicago (cost: 0) To Boston: Chicago Boston (cost: 9) To New York: Chicago New York (cost: 77) To Atlanta: Chicago Kansas City Atlanta (cost: 97) To Miami: Chicago Kansas City Atlanta Miami (cost: 0) To Dallas: Chicago Kansas City Dallas (cost: 09) To Houston: Chicago Kansas City Dallas Houston (cost: 6) All shortest paths from are: To 0: 0 (cost: ) 7

To : (cost: ) To : (cost: 4) To : (cost: 0) To 4: 4 (cost: 6) The program creates a weighted graph for Figure. in line 67. It then invokes the getshortestpath() function to return a ShortestPathTree object that contains all shortest paths from vertex (i.e., Chicago) (line 6). The printallpaths function displays all the paths (line 69). The graphical illustration of all shortest paths from Chicago is shown in Figure.0. The shortest paths from Chicago to the cities are found in this order: Kansas City, New York, Boston, Denver, Dallas, Houston, Atlanta, Los Angeles, Miami, Seattle, and San Francisco. Seattle 0 07 097 00 Chicago 77 9 Boston 4 New York San Francisco 67 0 66 Denver 4 99 Kansas City 60 64 Los Angeles 4 496 Dallas 9 6 7 0 7 Atlanta 66 Houston 7 9 Miami Figure.0 The shortest paths from Chicago to all other cities are highlighted. Check point.9 Trace Dijkstra s algorithm for finding shortest paths from Boston to all other cities in Figure...0 Is the shortest path between two vertices unique if all edges have different weights?. If you use an adjacency matrix to represent weighted edges, what would be the time complexity for Dijkstra s algorithm?

. What happens to the getshortestpath() function in WeightedGraph if the source vertex cannot reach all vertieces in the graph? Verify your answer by writing a test program that creates an unconnected graph and invoke the getshortestpath() function. How do you fix the problem by obtaining a partial shortest path tree?. If there is no path from vertex v to the source vertex, what will be cost[v]?.4 Assume that the graph is connected; will the getshortestpath function find the shortest paths correctly if lines - in WeightedGraph are deleted? <end check point>.6 Case Study: The Weighted Nine Tail Problem Key Point: The weighted nine tails problem can be reduced to the weighted shortest path problem. Section 4. presented the nine tail problem and solved it using the BFS algorithm. This section presents a variation of the problem and solves it using the shortest-path algorithm. The nine tail problem is to find the minimum number of the moves that lead to all coins being face down. Each move flips a head coin and its neighbors. The weighted nine tail problem assigns the number of flips as a weight on each move. For example, you can move from the coins in Figure.a to Figure.b by flipping the three coins. So the weight for this move is. H H H T T T H H H T T H H T T H H H (a) (b) Figure. The weight for each move is the number of flips for the move. The weighted nine tail problem is to find the minimum number of flips that lead to all coins face down. The problem can be reduced to finding the shortest path from a starting node to the target node in an edgeweighted graph. The graph has nodes. Create an edge from node v to u if there is a move from node u to node v. Assign the number of flips to be the weight of the edge. 9

Recall that we created a class NineTailModel in Section 4. for modeling the nine tail problem. We now create a new class named WeightedNineTailModel that extends NineTailModel, as shown in Figure.. NineTailModel #tree: Tree* +NineTailMod el() +get Shortes tpath(nodeindex: i nt): vector<int> +getnode(index: int): vector<char> +getindex(node: vector<char>&): int +printnode(node: vector<char>&): void #getedges(): vector<ed ge> #getflippednode(nod e: vector<char>&, position: int): int #flipacell(&node: vector<char>&, row: int, column: int): void A tree rooted at node. Constructs a model for th e Nine Tail problem and obtains th e tree. Returns a path from the specified n ode to the root. The path returned consists of the node labels in a vector. Returns a node consists of nine characters of H s and T s. Returns the index of the specified node. Displays the node to the console. Returns a vector of Edge objects for the graph. Flip the node at the specified position and returns the index of the flipped node. Flips th e node at th e specified row and colu mn. WeightedNineTailModel +Wei ghted Ni netai lmodel() +getnumberofflips(u: int): int -getnumberofflips(u: int, v: int): int -getedges(): vector<weightededge> Constructs a model for the weighted nine tail problem and obtains a ShortestPathTree rooted from the target node. Returns the number of flips from node u to the target node. Ret urns the number of di fferen t cells between the two nodes. Gets the weigh ted edges for the weighted nine tail problem. Figure. WeightedNineTailModel extends NineTailModel. The NineTailModel class creates a Graph and obtains a Tree rooted at the target node. WeightedNineTailModel is the same as NineTailModel except that it creates a WeightedGraph and obtains a ShortestPathTree rooted at the target node. The functions getshortestpath(int), getnode(int), getindex(node), getflippednode(node, position), 40