## Question 1 (45 minutes)

Behold the following graph:

On the next page, there are ten graphs. You are to answer the following, using those ten graphs when necessary.

• Part A: Which of the ten graphs is a final residual flow graph that would result when an augmenting path network flow algorithm runs on our graph.
• Part B: What is the value of the maximum flow of through the graph?
• Part C: What is the minimum cut of the graph?
• Part D: Which of the ten graphs is the residual flow graph after one step of the Edmonds-Karp algorithm?
• Part E: Which of the ten graphs is the residual flow graph after one step of the greedy depth-first search algorithm?
• Part F: Which of the ten graphs is the residual flow graph after one step of the algorithm that uses the modified Dijkstra's algorithm to find the augmenting path?
• Part G: Describe how you use the answer to part A to come up with the answer to part C. Be specific.

 A

 B

 C

 D

 E

 F

 G

 H

 I

 J

## Question 2 (15 minutes)

Using the graph drawn to the right, answer the following:
• Part A: Draw the minimum spanning tree of this graph.

• Part B: If one used Prim's algorithm starting at node S, give the order in which edges are added when constructing the minimum spanning tree. If an edge is not part of the minimum spanning tree, do not include it.

• Part C: If one used Kruskal's algorithm, give the order in which edges are added when constructing the minimum spanning tree. If an edge is not part of the minimum spanning tree, do not include it.

## Question 3 (30 minutes)

Here's a partially-completed implementation of Dijkstra's shortest path algorithm from one node to another:

 ```#include #include #include #include #include using namespace std; class Node { public: string name; int distance; Edge *backedge; queue edges; }; class Edge { public: int weight; Node *from; Node *to; }; class Graph { public: deque * Shortest_Path(Node *from, Node *to); vector nodes; multimap Dijkstra; }; ```
 ```deque * Graph::Shortest_Path(Node *from, Node *to) { deque *path; int i; Node *n; multimap ::iterator dit; for (i = 0; i < nodes.size(); i++) { nodes[i]->distance -1; nodes[i]->backedge = NULL; } from->distance = 0; Dijkstra.insert(make_pair(0, from)); while (!Dijkstra.empty()) { dit = Dijkstra.begin(); n = dit->second; Dijkstra.erase(dit); if (n == to) { path = new deque ; while (n != from) { path->push_front(n->backedge); n = n->backedge->from; } return path; } // The rest of Dijkstra's algorithm goes here } return NULL; } ```

Now, consider the graph below, left. Suppose we construct an instance of Graph holding this graph, and we call Shortest_Path from S to V.

When the while() loop begins, the state of Graph is pictured below, right.

• Part A: Draw the state of Graph after the first iteration of the while() loop. The answer sheet has a form for you to fill in -- fill in all blank parts.
• Part B: Draw the state of Graph after the second iteration of the while() loop.

## Question 4 (30 minutes)

You are given a two-dimensional vector of doubles, A. Suppose i < A.size() and suppose j < A[0].size(). Then we define the function f(i,j) as follows:
• f(0,0) = A[0][0].
• f(i,0) = A[i][0] + 0.5 * f(i-1, 0).
• f(0,j) = A[0][j] + 1.5 * f(0, j-1).
• f(i,j) = The minimum of ( A[i][j] + 0.5 * f(i-1, j)) and (A[i][j] + 1.5 * f(i, j-1)).
Now, behold the following class definition:

 ```typedef vector VD; class FindA { public: vector A; double f(int i, int j); } ```

Implement FindA::f() as a recursive dynamic program with memoization. If you need to add a variable or two to the class, go ahead and do so. Your implementation should assume that the elements in A are already implemented, that each A[i] is the same size, and that i and j are less than A.size() and A[0].size() respectively.