CS302 Final Exam - May 14, 2026
James S. Plank
First, please enter your username on the following line: ____________________
You are to answer the questions from this printed exam into Canvas. You will hand this exam
in at the end of class, and you may use the exam as scratch paper, but I will not read anything
on this exam with the exception of your username above.
If you have any comments to me, you
may communicate them with Question 2 of the canvas exam.
To help you plan, here are the point values of the questions:
Question 1: 0 points
Question 2: 0 points
Question 3: 20 points, 5 parts. You may want to do this last, because it takes some reading.
Question 4: 20 points, 5 parts.
Question 5: 8 points, 1-paragraph essay.
Question 6: 12 points, 4 parts.
Question 7: 8 points, 4 answers to the same question.
Question 8: 9 points, 6 answers to the same question.
Question 9: 6 points |
Question 10: 8 points | Questions 9 through 12 are
Question 11: 6 points | all parts of the same question.
Question 12: 3 points |
Question 1
Besides entering your username above, please also enter it on Question 1 in Canvas.
Question 2
If you have any comments to me, you may enter them in Question 2 on Canvas.
Question 3 - 20 points
For each problem below, I want you state the graph algorithm that you
would use to solve the problem, and if you know the running time,
state that. If you don't know the running time (e.g. Network Flow),
then just put an X for the running time. By the way, here are the
graph algorithms that we have studied in this class. You can use the abbreviations
given in your answer:
- DFS: Depth-First Search
- BFS: Breadth-First Search
- DA: Dijkstra's Algorithm
- NF: Network Flow
- MST: Minimum Spanning Tree
- TS: Topological Sort
Hint -- if the algorithm doesn't pop out to you, figure out what in the problem are nodes
and what are edges. Draw yourself an example graph for the
problem, and come up with the answer for that graph. That will help you identify which
algorithm is used to generate the answer.
Part 1:
I am the head of a transportation logistics company. We have two divisions -- air and train. Each of these divisions keeps the following information on cities and the routes between them. Cities are endpoints, where we can store goods. Routes may exist between two cities in either of the divisions. For each route, there is a time to travel the route, and a cost that it takes to travel the route.
Suppose I need to get goods from city A to city B, and I want to do it in cheapest manner, money-wise. Which algorithm should I use?
Suppose there are C cities and R routes. What is the running time of the algorithm?
Part 2:
A new management regime takes over from part 1, and dictates that every plane or train trip will cost $1,000. I need to get goods from city A to city B, and I want to do it in cheapest manner. Which algorithm should I use?
What is the running time?
Part 3:
A newer management regime takes over, and the costs of the routes return to
what they were in Part 1. Let's suppose that the cost of going from city A to city B is the same as going from city B to city A.
Management has inflicted another cost cutting measure on us -- we need to cancel as many routes as we can, but still make sure that our goods can get from any one city to another. We want to do this, but we want to make sure that the total cost of all routes is as small as possible. What algorithm do we use?
What is the running time?
Part 4:
A terrorist group has decided that they want to make it impossible to have goods go from Bangor, Maine to San Diego, CA. The first thing they will do is bomb all of the airports, so no more plane travel. Then, for each train route, they have determined the cost of bombing that route. What algorithm should they use to figure out which train routes to destroy that will achieve their goals in the cheapest manner?
What is the running time?
Part 5:
Question 4: The terrorist group has done their bombings. Some of them have been successful, and some of them haven't. You work for the government and know all of the success or failure of each bombing. You are asked if it's possible to get goods from Seattle to Miami. Which algorithm do you use to make this determination?
What is the running time?
Question 4
Question 4, Part 1
Perform a breadth-first search on the following graph, starting at node A, and print the nodes in the order in which you pull them off of the queue. Any valid breadth-first search will do.
In your answer, just list the nodes separated by commas.
5b456
|
 |
Question 4, Part 2
Perform a depth-first search on the following graph, starting at node A, and print the nodes in the order in which you set their visited fields. Any valid depth-first search will do.
In your answer, just list the nodes separated by commas.
369ff
|
 |
Question 4, Part 3
Print the nodes in the order of a topological sort. Any valid topological sort will do.
In your answer, just list the nodes separated by commas.
d720f
|
 |
Question 4, Part 4
Print the edges that compose a minimum spanning tree of this graph. Denote the edge from A to B as AB.
Separate the edges with commas, and you may print them in any order.
In case you care, here are the edges in sorted order:
7 IF
18 HE
30 HI
35 EB
43 FC
53 GD
55 DE
58 DA
59 EF
69 BC
77 GH
88 AB
cad1b
|
 |
Question 4, Part 5
The following is a weighted graph with source S and sink T. Please let me know the edges
that compose the minimum cut of this graph. Specify the edge between A and B as AB, and
separate each edge with a comma. You may specify the edges in any order.
367a7
|
 |
Question 5
Explain what it means for a problem to be in P.
Explain what it means for a problem to be in NP.
I'm expecting your answer to be 2-5 sentences, and I expect it to have some precision to it --
if you give me a vague hand-wavy answer, I will deduct points for it.
Question 6
Question 6, Part 1
Suppose that v has n elements and that l has m
elements. What is the big-O running time of the following procedure?
void p6b5b5(const vector <int> &v, list <int> &l)
{
size_t i;
for (i = 0; i < v.size(); i++) {
if (i % 2 == 0) {
l.erase(l.begin());
l.push_front(v[i]);
} else {
l.push_back(v[i]);
}
}
}
|
Question 6, Part 2
Suppose that v1 has n elements and that v2 has m
elements. What is the big-O running time of the following procedure?
int p9d1b2(const map <int, int> &v1, const map <long long, int> &v2)
{
long long i;
int rv;
rv = 0;
for (i = 0; i < (1LL << v1.size()); i++) {
if (v2.find(i) != v2.end()) rv++;
}
return rv;
}
|
Question 6, Part 3
Suppose we are performing network flow on a graph with V vertices and E
edges. And suppose we are using the Edmonds-Karp algorithm. What is the running time
to find a single augmenting path in the graph?
Question 6, Part 4
Suppose we are performing network flow on the following residual graph, using the
Edmonds-Karp algorithm. What is the next augmenting path that we will process in the graph
(Just list the nodes in order. You don't need to separate by commas).
Question 7
The following are the adjacency lists for a directed, acyclic graph. The format
is "[node:distance]":
0 : {[2:35],[4:37],[6:3],[7:9],[8:20]}
1 : {[3:1],[7:21],[8:13],[9:38]}
2 : {[3:43],[4:1],[6:45],[8:35]}
3 : {[4:1],[5:39],[8:30]}
4 : {[7:43]}
5 : {[8:48]}
6 : {[9:19]}
7 : {}
8 : {[9:22]}
9 : {}
We are using topological sort to find the shortest distance from node 0 to all of
the other nodes. In doing so, we will be maintaining three data structures:
- dist: A vector of the best known shortest paths to each node. We use 999
as a sentinal for "infinity".
- ninc: The number of incident edges to a node while processing the topological sort.
- q: A queue of nodes to process.
At the beginning of a pass of the algorithm, the data structures have the following values:
0 1 2 3 4 5 6 7 8 9
--- --- --- --- --- --- --- --- --- ---
dist: 0 999 35 999 37 999 3 9 20 999
ninc 0 0 0 1 2 1 1 1 3 2
Q: {2}
Now, to answer this question, I want you to focus on two types of event:
- When dist[i] changes its value. We will call this "D".
- When a node is added to q. We will call this "Q".
During this pass of the algorithm, there are four of these events (D or Q). I want you
to tell me what they are, in the following format:
- "D:4:55" means that dist[4] changes its value to 55.
- "Q:3" means that node 3 is added to q
There are four fill-in-the-blank slots for this question. Fill them in, one per event, in
the format above. The order does not matter.
53693
Question 8
We are doing network flow with source node S and sink node T. The following
is an adjacency matrix of the residual graph:
S A B C D T
-- -- -- -- -- --
S - 77 - 65 - -
A - - 27 40 - -
B - 10 - - - -
C 10 22 - - 27 44
D - - - - - 94
T - 23 10 - - -
We search for an augmenting path through the graph, and find the path SACT.
We process the residual graph, and in doing so either add, delete, or change
the value of six edges in the graph. I want you to tell me these six modifications
in the following format:
- If we have added an edge from A to B with a capacity of 5, then write "AB:5".
- If we have changed the capacity of the edge from A to B to a value of 5,
then write "AB:5".
- If we have deleted the edge from A to B, then write "AB:X".
Please enter the six modifications in the six spaces for this question.
66abe
For Questions 9 through 12
The function bif() operates on integers, and returns doubles. It is defined as follows:
- For i > 100 bif(i) is undefined.
- bif(100) = 1.
- bif(99) = 1.
- For 0 ≤ i ≤ 98, bif(i) = (1000,000,000+i)/(999,999,999+i) * bif(i+1) * bif(i+2).
- For i < 0 bif(i) is undefined.
You are implementing bif, and so far, this is what you have:
#include <vector>
#include <iostream>
using namespace std;
class BIF {
public:
const double A = 1000000000; // Yes, I know this only compiles with C++11 or later.
const double B = 999999999;
double bif(int x);
};
double BIF::bif(int x)
{
return -1; // Unimplemented.
}
int main()
{
int x;
BIF b;
cin >> x;
cout << b.bif(x) << endl;
return 0;
}
|
You are going to implement Bif::bif() using all four steps of dynamic programming,
one step per part. Do not just implement step 4 and think you're done -- I want you to
implement all four steps.
Question 9 - 6 points
Implement Bif::bif() with dynamic programming, step 1. Just implement double BIF::bif(int x) -- the class definition does not need to be modified.
Question 10 - 8 points
Now do "Step 2". Do not change the prototype of BIF::bif(), but you will have to
add a variable to the BIF class. In the box for this problem, specify what you need to add to
the BIF class, and then re-implement BIF::Bif().
Question 11 - 6 points
Now do "Step 3". You should not need to change the BIF class specification, but you
need to re-implement BIF::Bif().
Question 12 - 3 points
Finally, do "Step 4". Again, you should not need to change the BIF
class specification, but you need to re-implement BIF::Bif().