COMP 271: Design and Analysis of Algorithms

COMP 271: Design and Analysis of Algorithms
Hong Kong University of Science & Technology
Spring, 2007
Homework 2
Assigned: 1/3/06
Due Date: 19/3/06, 4pm
All assignments should be submitted to the assignment collection box for COMP271
outside room 4213A. No late submission is allowed.
Question 1: Let G = (V, E) be a connected undirected graph in which all edges have
weight 1 or 2. Give an O(|V| + |E|) algorithm to compute a minimum spanning tree of
G. Justify the running time of your algorithm. (Hint: Modify Prim's algorithm).
Solution:
This can be done in several ways. Here is a brief sketch of one solution.
Idea of the Algorithm: Since all edges in the graph have weight 1 or 2, we can
design a simple data structure so that “queue” operations such as Extract_Min( ) and
Decrease_Key(u, newKey) can be performed in O(1) time each, rather than O(log n)
time. By replacing the priority queue in Prim’s algorithm with this data structure, we
reduce the time complexity to O(|V| + |E|).
Implementation Issue: We use two FIFO queues Q1 and Q2 to achieve the function of
a priority queue. Q1 contains items of weight 1 and Q2 contains items of weight 2.

Operation Extract_Min() can be done in O(1) time as follows: If Q1 is not empty,
dequeue the first item from the front of Q1; else if Q1 is empty, dequeue the first
item from the front of Q2.

Operation Decrease_Key(u, newKey) can be done in O(1) time as follows: If
newKey is 2 (or 1), enqueue the element u to the rear of Q2 (or Q1).
By replacing the priority queue with the two FIFO queues, Prim’s algorithm can
compute a MST of G in O(|V| + |E|) time.
1
Question 2: We are running one of these three algorithms on the graph below, where
the algorithm has already "processed" the bold-face edges. (Ignore the directions on
the edges for Prim's and Kruskal's algorithms.)

Prim's for the minimum spanning tree, starting from s.

Kruskal's for the minimum spanning tree.

Dijkstra's for shortest paths from s.
a) Which edge would be added next in Prim's algorithm?
Solution:
Edge BE, since Prim's algorithm always adds an edge connected with "processed"
subgraph yet with the minimum weight.
b) Which edge would be added next in Kruskal's algorithm?
Solution:
Edge FG, since Kruskal's algorithm always adds an "unprocessed" edge with the
minimum weight in the graph that does not introduce the cycle.
2
c) Which vertex would be marked next in Dijkstra's algorithm? Which final edge
would Dijkstra's algorithm choose as part of the shortest path to this vertex (i.e. which
edge connects to this vertex as part of the shortest path from s)?
Solution:
Vertex D; Edge CD.
In the sequel, we give the explanation.
Status of arrays in the figure is:
v
S
d[v]
0
pred[v] nil
color[v] B
Priority queue:
A
2
S
B
v
d[v]
B
5
A
B
D
7
C
1
S
B
D
7
C
W
F
8
E
10
E F
10 8
B C
W W
G
∞
nil
W
G
∞
Therefore, the next popped vertex from the priority queue is D.
Obviously, the final edge connecting with D on the shortest path from s to D is CD.
3
Question 3: Given a free tree T and a node v of T, the eccentricity of v is the length of
a longest path from v to any other node of T. A node of T with minimum eccentricity
is called a center of T. Design an efficient algorithm that computes a center of T. Is the
center unique? If not, how many distinct centers can a free tree have? (a free tree is a
tree that is not rooted)
Solution:
Basic idea: Since T is a tree, there is no cycle in T. Each time we mark leaf nodes of T
and conceptually remove them from T until finally only one or two leaf nodes are left,
which is/are exactly the center(s).
Procedure of algorithm:
(a) Remove all leaves of T. Let the remaining tree be T1.
(b) Remove all leaves of T1. Let the remaining tree be T2.
(c) Repeat the “remove” operation as follows: Remove all leaves of Ti. Let remaining
tree be Ti+1.
(d) Once the remaining tree has only one node or two nodes, stop! Suppose now the
remaining tree is Tk.
(e) If Tk has only one node, that is the center of T. The eccentricity of the center node
is k.
(f) If Tk has two nodes, either can be the center of T. The eccentricity of the center
node is k + 1.
Detailed implementation:
Algorithm Eccentricity(G)
begin
foreach u in V do
color[u] = white;
end
counter = n; // the number of vertices left
foreach u in V do
while color[u] = white do
Mark_Leaf(u);
if counter = 1 or 2
then
return the grey vertex (vertices) in G
end
change all entries of color[] in grey to white color
end
end
end
4
Algorithm Mark_Leaf(u)
begin
degree = 0;
color[u] = grey;
foreach v in Adj(u)
if color[v] = white or grey
then
degree++;
end
end
if degree = 1
then
color[u] = black;
//leaf node
counter--;
else
foreach v in Adj(u)
if color[v] = white
Mark_Leaf(v);
end
end
end
end
The center of a free tree may not be unique. As a simple example in the following
figures, a path with 3 nodes (left figure) has only one center (the middle node with
degree 2), whereas that with 4 nodes (right figure) has two centers (two middle nodes
with degree 2).
(a)
(b)
A free tree can only have 1 or 2 centers.
5
Question 4: A directed graph is acyclic if there aren't any paths that start and end at
the same vertex. A vertex is called a source if it has no incoming edges, and a vertex
is called a sink if it has no out going edges.
Consider a directed acyclic graph with one source and one sink. Design an efficient
algorithm to count the number of paths that start from the source and end at the sink.
Analyze the worst-case running time of your algorithm.
Solution:
Algorithm Shell(G)
begin
foreach u in V do
cnt[u] = 0;
---------------------------- 1
color[u] = white;
---------------------------- 1
end
find source src and sink dest in G; ------------------ c(n+e)
Path_Counter(src, dest);
return cnt[src];
end
Algorithm Path_Counter(src, dest)
begin
if src = dest
---------------------------- 1
then
cnt[src] = 1;
---------------------------- 1
color[src] = black; ---------------------------- 1
return;
end
foreach u in Adj(src) do // out-degree of src
if color[u] = white ---------------------------- 1
then
Path_Counter(u, dest);
end
cnt[src] = cnt[src] + cnt[u]; ----------------- 1
end
color[src] = black;
end
Let Tsrc be the number of operations in Path_Counter (src, dest) except for recursive
call. We have 1 + out-degree(src) ≤ Tsrc ≤ 1+2 * out-degree(src). Therefore, the total
running time is (2n + c(n + e)) + Σsrc ∈ V Tsrc, which is between (2n + c(n + e)) + (n+e)
and (2n + c(n + e)) + (n + 2e). Hence, in the worst case, the complexity of our
algorithm is Θ(n+e).
6