DSC 40B

Quiz 06

Practice problems for topics on Quiz 06.

Tags in this problem set:

Problem #189

Tags: lecture-10, graph theory

What type of graph would be best for representing a network of friends on social media, where friendships are mutual? (i.e, if person A is person B's friend, person B is also person A's friend)

Solution

An undirected graph. Since friendship is symmetric, an edge between A and B has no direction.

Problem #190

Tags: lecture-10, graph theory

Consider the graph below

What is the out degree of node \(0\)?

Solution

Answer: 3. Node 0 has edges to 2, 4, and 5.

Problem #191

Tags: lecture-10, graph theory

What is the out-degree of node \(u\) in the graph shown below?

Solution

4

Problem #192

Tags: lecture-10, graph theory

Let \(V = \{a, b, c, d\}\) and \(E = \{(a,b), (a,a), (a,c), (d,b), (c,a)\}\) be the nodes and edges of a directed graph. How many predecessors does node \(b\) have?

Solution

2

Problem #193

Tags: lecture-10, graph theory

Suppose \(u\) is a node in a complete, undirected graph \(G = (V,E)\). What is the degree of \(u\)? Remember, an undirected graph is complete if it contains every possible edge.

Solution

\(|V| - 1\)

Problem #194

Tags: lecture-10, graph theory

Let \(G = (V, E)\) be a directed graph, and suppose \(u, v, w \in V\) are all nodes. True or False: if \(w\) is reachable from \(v\), and \(v\) is reachable from \(u\), then \(w\) is reachable from \(u\).

Solution

True.

There is a path from \(u\) to \(v\) and a path from \(v\) to \(w\). Following the first path and then the second gives a path from \(u\) to \(w\)(all of the edges point in the right direction, since each path follows its edges forward).

Problem #195

Tags: lecture-10, connected components, graph theory

Let \(C\) be a connected component in an undirected graph \(G\). Suppose \(u_1\) is a node in \(C\) and let \(u_2\) be a node that is reachable from \(u_1\). True or False: \(u_2\) must also be in the same connected component, \(C\).

Solution

True.

A connected component contains every node that is reachable from any of its nodes; it is a maximal set of nodes that can all reach one another. Since \(u_2\) is reachable from \(u_1\), it is in the same component as \(u_1\), which is \(C\).

Problem #196

Tags: lecture-10, graph theory

Let \(v = \{a, b, c, d, e, f, g\}\) and \(E = \{(a,g), (b,d), (d, e), (f, d)\}\). How many connected components does the undirected graph \(G =(V, E)\) have?

Solution

3

Problem #197

Tags: lecture-10, connected components

Consider the undirected graph \(G = (V, E)\) with

\(V = \{0, 1, 2, 3, 4, 5, 6, 7\}\)\(E = \{(0, 1), (3, 6), (1, 5), (2, 4), (3, 4)\}\)

What are the connected components of \(G\)?

Solution

\(\{\{0, 1, 5\}, \{2, 3, 4, 6\}, \{7\}\}\). The edges \((0,1)\) and \((1,5)\) connect 0, 1, and 5. The edges \((2,4)\), \((3,4)\), and \((3,6)\) connect 2, 3, 4, and 6. Node 7 has no edges, so it is a connected component by itself.

Problem #198

Tags: lecture-10, connected components

Let \(G = (V,E)\) be an undirected graph with:

True or False: \(\{b, d, g\}\) is a connected component of this graph.

True False
Solution

False. The connected components of this graph are \(\{a, e, f\}\) and \(\{b, c, d, g, h\}\).

Remember: a connected component has to contain all nodes reachable from any node in the component. While \(b\), \(d\), and \(g\) are all reachable from one another (and are ``connected''), they do not form a connected component because there are more nodes reachable from this group: namely, \(h\) and \(c\).

Problem #199

Tags: lecture-10, connected components

Let \(G = (V,E)\) be an undirected graph with:

True or False: \(\{a, d, e\}\) is a connected component of this graph.

True False
Solution

False.

Node \(c\) is also reachable from \(a\) via the edge \((a, c)\), so \(\{a, d, e\}\) isn't a maximal set of connected nodes. The connected component containing \(a\) is \(\{a, c, d, e\}\).

Problem #200

Tags: lecture-10, connected components, graph theory

Let \(G = (V, E)\) be an undirected graph, and suppose that \(u, v, \) and \(w\) are three nodes in \(V\). Suppose that \(u\) and \(v\) are in the same connected component, but \(u\) and \(w\) are not in the same connected component. True or False: it is possible that \(v\) and \(w\) are in the same connected component.

True False
Solution

False.

If \(v\) and \(w\) were in the same connected component, then there would be a path from \(u\) to \(v\) and a path from \(v\) to \(w\), and putting them together gives a path from \(u\) to \(w\). That would put \(u\) and \(w\) in the same component, which contradicts what we were told. (In other words, the connected components split the nodes into non-overlapping groups.)

Problem #201

Tags: lecture-10, graph theory

An undirected graph has 5 nodes. What is the greatest number of edges it can have?

Solution

10

Problem #202

Tags: lecture-10, graph theory

You are told that a directed graph has 10 nodes. If the graph is fully connected with the exception of self loops (meaning, it has all possible edges except self loops) how many edges are there?

Solution

Answer: 90. Each of the 10 nodes has an edge to each of the other 9 nodes, giving \(10 \times 9 = 90\) edges. (Equivalently, \(10^2 = 100\) possible ordered pairs, minus the 10 self loops.)

Problem #203

Tags: lecture-10, graph theory

Let \(G\) be an undirected graph. Suppose that the degree of every node in the graph is greater than or equal to one. True or False: \(G\) must be connected.

True False
Solution

False.

Take four nodes \(a, b, c, d\) with edges \((a, b)\) and \((c, d)\). Every node has degree 1, but the graph has two connected components, \(\{a, b\}\) and \(\{c, d\}\).

Problem #204

Tags: lecture-10, connected components, graph theory

Suppose \(G = (V, E)\) is an undirected graph. Let \(k\) be the number of connected components in \(G\). True or False: it is possible that \(k > |E|\).

Solution

True.

For example, a graph with 3 nodes and no edges has \(k = 3\) connected components (each node is its own component) but \(|E| = 0\).

Problem #205

Tags: lecture-10, graph theory

Let \(G = (V, E)\) be a directed graph with \(|V| > 1\). Suppose that every node in \(G\) is reachable from every other node. True or False: each node in the graph must have an out-degree of at least one and an in-degree of at least one.

Solution

True.

Pick any node \(u\), and let \(v\) be some other node (one exists because \(|V| > 1\)). Since \(v\) is reachable from \(u\), there is a path out of \(u\), and the first edge of that path leaves \(u\), so \(u\) has out-degree at least one. Similarly, since \(u\) is reachable from \(v\), the last edge of that path enters \(u\), so \(u\) has in-degree at least one.

Problem #206

Tags: lecture-10, graph theory

Let \(G = (V, E)\) be a connected, undirected graph with 16 nodes and 35 edges. What is the greatest possible number of edges that can be in a simple path within \(G\)?

Solution

15

Problem #207

Tags: lecture-10, connected components, graph theory

Suppose an undirected graph \(G = (V,E)\) has two connected components, \(C_1\) and \(C_2\). Suppose that \(|C_1| = 4\) and \(|C_2| = 3\). What is the largest that \(|E|\) can possibly be?

Solution

Answer: 9. To load a graph with the most edges, make each connected component "fully connected". The most edges we can put in a component with 4 nodes is \(4 * 3 / 2 = 6\), and the most we can put into a component with 3 nodes is \(3 * 2 / 2 = 3\). Therefore, we can put at most 9 edges in this graph.

Problem #208

Tags: lecture-10, connected components

Suppose an undirected graph has 3 connected components and 7 nodes. What is the maximum number of edges it can have?

Solution

10

Problem #209

Tags: lecture-10, graph theory

Suppose an undirected graph has 16 edges. What is the smallest number of nodes it can have?

Solution

7

Problem #210

Tags: lecture-10, graph theory

A directed graph has 10 edges. What is the smallest number of nodes it can have?

Solution

4

Problem #211

Tags: lecture-10, graph theory

Suppose a directed graph has 5 nodes and 3 edges. What is the greatest possible degree of any node in the graph?

Solution

Remember that nodes can have self loops, and that the degree of a node with only a self-loop is 2. So a node that has a self loop and two other edges leaving it has a degree of 4.

Problem #212

Tags: lecture-10, graph theory

Consider the graph below

How many simple paths are there from \(0\) to \(5\)?

Solution

Answer: 3. They are \(0 \to 5\), \(0 \to 4 \to 5\), and \(0 \to 2 \to 4 \to 5\).

Problem #213

Tags: lecture-10, graph theory

Consider the graph below

True or False: there are infinitely many paths from \(0\) to \(5\). (Here, "path" means any path, not necessarily a simple path.)

Solution

False. Paths may repeat nodes, so there would be infinitely many paths from 0 to 5 if some path from 0 to 5 could go around a cycle. But this graph has no cycles (every edge goes "forward"), so no path can repeat a node, and the only paths from 0 to 5 are the three simple paths \(0 \to 5\), \(0 \to 4 \to 5\), and \(0 \to 2 \to 4 \to 5\).

Problem #214

Tags: lecture-10, connected components

Let \(G\) be an undirected graph, and suppose \(u\) and \(v\) are two nodes belonging to the same connected component of \(G\), with \(v\) being a neighbor of \(u\). That is, the edge \((u, v)\) is in \(G\).

Let \(G'\) be the graph obtained from \(G\) by deleting the edge \((u, v)\). True or False: \(u\) and \(v\) must still be in the same connected component of the new graph, \(G'\).

True False
Solution

False.

If the edge \((u, v)\) is the only path between them, deleting it disconnects them. For example, if \(G\) has just the two nodes \(u\) and \(v\) and the single edge \((u, v)\), then after deleting it, \(u\) and \(v\) are each in their own connected component. (They do stay connected if some other path between them exists, but that isn't guaranteed.)

Problem #215

Tags: lecture-10, connected components

Suppose that every node in an undirected graph with \(n\) nodes has degree 2.

True or False: \(G\) must have one connected component.

True False
Solution

False.

Consider a graph with 6 nodes made up of two separate triangles. Every node has degree 2, but the graph has two connected components.

Problem #216

Tags: lecture-10, graph theory

Let \(G=(V,E)\) be an undirected graph with \(V=\{a,b,c,d,e\}\) and \(E=\{(a,b),(c,d),(e,a),(b,c),(e,d),(d,a)\}\).

True or False: it is possible to color nodes of \(G\) with red and blue such that there are no edges between nodes of the same color.

True False
Solution

False.

The edges \((a, d)\), \((d, e)\), and \((e, a)\) form a triangle. Whichever colors we give \(a\), \(d\), and \(e\), two of these three nodes must share a color, and they are joined by an edge.

Problem #217

Tags: lecture-10, graph theory

Let \(G = (V, E)\) be a directed graph with the property that there is a node \(u\) in \(G\) such that every other node in \(G\) is reachable from \(u\).

Let \(H \) be the directed graph obtained from \(G\) by reversing the direction of every edge. True or False: there must be a node \(v\) in \(H\) such that every other node in \(H\) is reachable from \(v\).

True False
Solution

False. Consider the graph \(a \leftarrow b \rightarrow c\). Every node is reachable from \(b\). Now flip the edges to get the graph: \(a \rightarrow b \leftarrow c\). There's no node from which every other node is reachable.

Problem #218

Tags: lecture-10, graph representations

Let \(A\) be the adjacency matrix representing a directed graph with $n$ nodes. What is the greatest possible sum of any row of \(A\)?

Solution

\(n\)

Problem #219

Tags: lecture-10, graph representations

Let \(A\) be the adjacency matrix representing a undirected graph with \(n\) nodes. What is the greatest possible sum of any row of \(A\)?

Solution

\(n - 1\). The sum of row \(i\) is the degree of node \(i\). Since an undirected graph has no self-loops, a node can be adjacent to at most the other \(n - 1\) nodes.

Problem #220

Tags: lecture-11, aggregate analysis, graph representations

Suppose a graph \(G = (V, E)\) is stored using an adjacency list representation in the variable adj_list. What is the time complexity of the below code?

for lst in adj_list:
    for u in lst:
        print(u)
Solution

\(\Theta(V + E)\)

Problem #221

Tags: lecture-11, aggregate analysis

Suppose a graph \(G = (V, E)\) is stored using an adjacency list representation in the variable adj_list. What is the time complexity of the below code?

for u, lst in enumerate(adj_list):
    for v in lst:
        print(u, v, "is an edge")
Solution

2nd option: \(\Theta(V + E)\)

Problem #222

Tags: lecture-11, aggregate analysis

Suppose the code below is run on a graph \(G = (V, E)\). What is its time complexity? You may assume that \(|E| \geq 1\).

for u in graph.nodes:
    for v in graph.neighbors(u):
        print(u, v)
Solution

\(\Theta(V + E)\)

Problem #223

Tags: lecture-10, graph representations

An isolated node in an undirected graph is a node that has no neighbors.

Suppose a graph \(G = (V, E)\) is represented using an adjacency matrix. What is the best possible worst-case time complexity of an efficient algorithm for computing the number of isolated nodes in the graph? State your answer as a function of \(|V|\) and \(|E|\) using asymptotic notation.

Solution

\(\Theta(V^2)\)

Problem #224

Tags: lecture-10, graph representations

An ``isolated node'' in a graph is a node that has no edges attached to it.

What is the worst case time complexity of an efficient algorithm that checks to see if a graph \(G = (V, E)\) has an isolated node? You should assume that the graph is represented as an adjacency list.

Solution

\(\Theta(V)\)

Problem #225

Tags: lecture-10, graph representations

Let \(A\) be the adjacency matrix of the graph shown below:

Let \(\vec{a}^{(1)}\) be the first row of \(A\) and \(\vec{a}^{(2)}\) be the second row of \(A\). What is \(\vec{a}^{(1)}\cdot\vec{a}^{(2)}\)? That is, what is the dot product between the first row of \(A\) and the second row of \(A\)? Your answer should be in the form of a number.

It may help to recall that the dot product between vectors \(\vec x = (x_1, \ldots, x_d)^T\) and \(\vec y = (y_1, \ldots, y_d)^T\) is equal to \(x_1 y_1 + x_2 y_2 + \ldots + x_d y_d\).

Solution

4

Problem #226

Tags: lecture-10, graph theory

The adjacency matrix of a directed graph with nodes \(u_1, \ldots, u_8\) is shown below:

\[\begin{pmatrix} 0 & \textbf{1} & 0 & 0 & 0 & 0 & 0 & 0 \\ \textbf{1} & 0 & \textbf{1} & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & \textbf{1} & 0 & 0 & 0 & 0 \\ 0 & \textbf{1} & 0 & 0 & \textbf{1} & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & \textbf{1} & 0 & 0 \\ 0 & 0 & 0 & \textbf{1} & 0 & 0 & \textbf{1} & 0 \\ \textbf{1} & 0 & \textbf{1} & 0 & 0 & 0 & 0 & \textbf{1} \\ \textbf{1} & 0 & 0 & \textbf{1} & 0 & 0 & 0 & 0 \\ \end{pmatrix}\]

True or False: there is a path from node \(u_1\) to node \(u_8\).

True False
Solution

True.

Reading each row as the edges leaving that node, we can follow the path \(u_1 \to u_2 \to u_3 \to u_4 \to u_5 \to u_6 \to u_7 \to u_8\).

Problem #227

Tags: lecture-11, breadth first search

Suppose you run a BFS on the graph below, however, the BFS is modified so that any time a node is popped from the queue, the message Node popped!!! is printed to the screen.

How many times is the message printed?

Solution

Answer: 6. Every node reachable from the source is added to the queue exactly once and popped exactly once. This graph is connected, so all 6 nodes are popped, no matter which node the BFS starts at.

Problem #228

Tags: lecture-11, breadth first search

Suppose you are performing a BFS on the following graph, starting on node 0: In which of the following orders are the nodes visited, assuming that the BFS algorithm produces neighbors in numerical order?

Solution

0, 1, 3, 5, 4, 2. Visiting 0 adds 1 and 3 to the queue. Visiting 1 adds 5. Visiting 3 adds 4. Visiting 5 adds nothing new (4 is already pending). Visiting 4 adds 2. Finally 2 is visited.

Problem #229

Tags: lecture-11, breadth first search

Suppose a breadth first search is run on the graph below using node \(d\) as the source. Adopt the convention that a node's neighbors are produced in alphabetical order.

What is the node popped from the queue after node \(g\)?

Solution

\(e\). The nodes are popped in the order \(d, f, q, r, g, e, v\). Popping \(d\) adds \(f, q, r\); popping \(f\) adds \(g\); popping \(q\) adds \(e\); popping \(r\) adds \(v\). So the queue is then \(g, e, v\), and \(e\) comes right after \(g\).

Problem #230

Tags: lecture-11, breadth first search

Consider running a breadth-first search (BFS) on the graph shown below, using node \(s\) as the source and adopting the convention that neighbors are produced in ascending order by label.

How many nodes will be popped from the queue before node \(u_8\) is popped?

Solution

9

Problem #231

Tags: lecture-11, breadth first search

Define a circle graph with \(n\) nodes to be an undirected graph \(G = (V, E)\) with nodes \(u_1, u_2, \ldots, u_n\) and edges \((u_1, u_2), (u_2, u_3), \ldots, (u_{n-1}, u_n)\), along with one additional edge \((u_n, u_1)\) completing the cycle. An example of a circle graph with 6 nodes is shown below:

What is the time complexity of breath-first search when run on a circle graph with \(n\) nodes? State your answer as a function of \(n\) using asymptotic notation.

Solution

\(\Theta(n)\)

Problem #232

Tags: lecture-11, breadth first search

Suppose a ``2-chain'' graph with \(n\) nodes is constructed by taking \(n\) nodes labeled 1, 2, \(\ldots\), \(n\), and, for each node \(u\), making an edge to nodes \(u + 1\) and \(u + 2\)(if they are in the graph).

For example, such a graph with \(n = 7\) looks like:

Suppose BFS is run on a 2-chain graph with \(n\) nodes, using node 1 as the source. What is the time taken as a function of \(n\)? State your answer using asymptotic notation.

Solution

\(\Theta(n)\)

Problem #233

Tags: lecture-11, breadth first search

The code below is a modified version of BFS shown in class. This modification has a single addition: a print statement. A comment in the code indicates where the print statement is located.

def bfs(graph, source):
    """Start a BFS at `source`."""
    status = {node: 'undiscovered' for node in graph.nodes}
    status[source] = 'pending'
    pending = deque([source])

    while pending: 
        u = pending.popleft()
        for v in graph.neighbors(u):
            print("here!") # <--- this is the print statement
            if status[v] == 'undiscovered':
                status[v] = 'pending'
                pending.append(v)
        status[u] = 'visited'

Suppose this modified BFS is run on the following graph, starting at node \(a\).

How many times will "here!" be printed? Your answer should be an exact number.

Solution

10

Problem #234

Tags: lecture-11, breadth first search

Consider the following modification of BFS, with an added print statement:

from collections import deque

def modified_bfs(graph, source):
    """Start a BFS at `source`."""
    status = {node: 'undiscovered' for node in graph.nodes}
    status[source] = 'pending'
    pending = deque([source])

    while pending:
        u = pending.popleft()
        for v in graph.neighbors(u):
            if v == 9:
                print("Here!") # <-- this is the added print statement
            if status[v] == 'undiscovered':
                status[v] = 'pending'
                pending.append(v)

        status[u] = 'visited'

Consider running this algorithm on the following graph, starting at node \(1\):

How many times will "Here!" be printed?

Solution

2

Problem #236

Tags: lecture-11, breadth first search

Consider calling full_bfs on a directed graph, and recall that full_bfs will make calls to bfs until all nodes have been marked as visited.

True or False: the number of calls made to bfs depends on the order in which graph.nodes produces the graph's nodes. That is, if nodes are produced in a different order, the number of calls to bfs may be different.

True False
Solution

True.

Consider the graph with the single edge \((a, b)\). If \(a\) is produced first, bfs(a) discovers \(b\) and only one call is needed. If \(b\) is produced first, bfs(b) cannot reach \(a\), so a second call is needed.

Problem #237

Tags: time complexity, lecture-11, breadth first search

Suppose an undirected graph with \(n\) nodes satisfies the property that every node has degree \(n/2\). What is the time complexity of running full BFS on this graph?

Solution

\(\Theta(n^2)\). Full BFS takes \(\Theta(V + E)\) time. The sum of the degrees is \(n \cdot n/2\), and each edge is counted twice in this sum, so there are \(n^2/4\) edges. So the time is \(\Theta(n + n^2/4) = \Theta(n^2)\).

Problem #238

Tags: lecture-11, breadth first search

Suppose a connected, undirected graph \(G\) has \(n\) nodes, half of which are ``red'' and half of which are ``blue''. Each red node shares an edge with \(\log_2 n\) blue nodes, and the only edges in the graph are between red and blue nodes.

What is the time complexity of BFS when run on \(G\)? Your answer should be in asymptotic notation and in terms of \(n\), in as simplest terms possible.

Solution

\(\Theta(n \log n)\)

Problem #239

Tags: lecture-10, graph theory

A ``hub node'' in a graph is a node that has an edge to all the other nodes in the graph.

What is the worst case time complexity of an efficient algorithm that checks to see if a graph \(G = (V,E)\) has a hub node? You should assume that the graph is represented as an adjacency list. State your answer in asymptotic notation and in terms of \(V\) and \(E\).

Note: in studying, you might have come across a problem in the practice bank about ``hub and spoke'' graphs. This question is related, but not the same!

Solution

\(\Theta(V)\)

Problem #240

Tags: lecture-11, connected components, breadth first search

Suppose you are running a full BFS on a graph. You are using the following code from lecture to run your full BFS, with some small modifications to include two new print statements:

from collections import deque

def bfs(graph, source, status=None):
    """Start a BFS at `source`."""
    if status is None:
        status = {node: 'undiscovered' for node in graph.nodes}

    status[source] = 'pending'
    pending = deque([source])

    # while there are still pending nodes
    while pending:
        u = pending.popleft()
        for v in graph.neighbors(u):
            # explore edge (u, v)
            print('foo') # <- this is new
            if status[v] == 'undiscovered':
                status[v] = 'pending'
                # append to right
                pending.append(v)
        status[u] = 'visited'

def full_bfs(graph):
    status = {node: 'undiscovered' for node in graph.nodes}
    for node in graph.nodes:
        if status[node] == 'undiscovered':
            print("bar") # <- this is also new
            bfs(graph, node, status)

After running the full BFS, you find that the word “foo” has been printed 2 times, and the word “bar” has been printed 5 times. Assuming that the graph has 1 edge (but an unknown number of nodes), which of the following is true about the graph in question?

Solution

There are 5 connected components, and it is undirected. "bar" is printed once each time full_bfs starts a new BFS, and in an undirected graph each new BFS starts in a new connected component, so there are 5 connected components. "foo" is printed once each time an edge is explored. In an undirected graph, each edge is explored twice (once from each endpoint), while in a directed graph it is explored only once. Since there is 1 edge and "foo" was printed 2 times, the graph is undirected.

Problem #242

Tags: time complexity, lecture-11, aggregate analysis, breadth first search

Consider the following modification of BFS, where there are two new lines of code. What is the time complexity in terms of \(|V|\) and \(|E|\)?

from collections import deque

def foo(graph):
    status = {node: 'undiscovered' for node in graph.nodes}
    for u in graph.nodes:
        if status[u] == 'undiscovered':
            bar(graph, u, status)

def bar(graph, source, status):
    status[source] = 'pending'
    pending = deque([source])

    # while there are still pending nodes
    while pending:
        u = pending.popleft()
        for v in graph.neighbors(u):
            # explore edge (u,v)
            if status[v] == 'undiscovered':
                status[v] = 'pending'
                pending.append(v)
            for v in graph.nodes:
                print(v)
        status[u] = 'visited'
Solution

\(\Theta(V + VE)\). Without the two new lines, this is a full BFS, which takes \(\Theta(V + E)\) time. The new inner loop runs once each time an edge is explored, and each time it takes \(\Theta(V)\) time. By an aggregate analysis, edges are explored \(\Theta(E)\) times in total, so the new lines add \(\Theta(VE)\) time. The total is \(\Theta(V + E + VE) = \Theta(V + VE)\). (We can't drop the \(V\) term: when there are no edges, the code still takes \(\Theta(V)\) time.)

Problem #243

Tags: lecture-11, aggregate analysis, breadth first search

Consider the code below, which is a modification of the code for bfs given in lecture:

from collections import deque

def modified_full_bfs(graph):
    status = {node: 'undiscovered' for node in graph.nodes}
    for node in graph.nodes:
        if status[node] == 'undiscovered':
            modified_bfs(graph, node, status)

def modified_bfs(graph, source, status=None):
    """Start a BFS at `source`."""
    if status is None:
        status = {node: 'undiscovered' for node in graph.nodes}

    status[source] = 'pending'
    pending = deque([source])

    # while there are still pending nodes
    while pending: 
        u = pending.popleft()
        for v in graph.neighbors(u):
            # explore edge (u,v)
            if status[v] == 'undiscovered':
                status[v] = 'pending'
                # append to right
                pending.append(v)
                for z in graph.nodes:   # <----- new line!
                    print(z, status[z]) # <----- new line!

        status[u] = 'visited'

Notice the two new lines; these lines print all node statuses any time that an undiscovered node has been found.

What is the time complexity of this modified modified_full_bfs? State your answer in asymptotic notation in terms of the number of nodes, \(|V|\), and the number of edges, \(|E|\). You may assume that the graph is represented using an adjacency list, and that it is connected.

Solution

\(\Theta(V^2)\).

First, the newly-added code (the for z in graph.nodes loop), takes \(\Theta(V)\) time each time the loop is encountered. The crux is: how many times is that loop encountered?

This loop is encountered every time we add a node to the queue (except for the root node, which we add to the queue right at the beginning of BFS). Since this is a connected graph, each node will get added to the pending queue exactly once, meaning that this new code is encountered exactly\(V-1\) times (the \(-1\) is subtracting the root node; the loop isn't encountered when we change it to pending).

Since the new code takes \(\Theta(V)\) time each time it's encountered, and since it's encountered \(\Theta(V)\) times, the total time complexity of the loop is \(\Theta(V^2)\).

You might wonder why the time complexity isn't \(\Theta(VE)\), since the new code is within the loop that ``explores'' each edge in the graph, and we know that it makes a total of \(2|E|\) iterations when the graph is undirected. This is true, but recognize that the new code only executes when the if-statement before it is True, and this will happen on only a subset of the \(2|E|\) iterations. In fact, it will happen exactly \(|V|-1\) times, as we argued above.

Problem #244

Tags: lecture-11, aggregate analysis

A ``hub and spoke'' graph with \(n\) nodes consists of a single ``hub'' node \(h\) along with \(n - 1\) ``spoke'' nodes, \(u_1, \ldots, u_{n-1}\) and \(n - 1\) edges from the hub node \(h\) to each of the spoke nodes. For example, a ``hub and spoke'' graph with 8 nodes looks like the below:

What is the worst case time complexity of an optimal algorithm which takes as input an arbitrary graph \(G = (V, E)\) and determines if it is a ``hub and spoke'' graph? You may assume that the graph is represented as an adjacency list and that the total number of edges in the graph can be retrieved in constant time.

Solution

\(\Theta(1)\) Here's the algorithm. First, check that the number of edges is \(|V| - 1\). If not, it's not a ``hub and spoke'' graph. This takes constant time, by the assumption that the total number of edges can be retrieved in constant time.

Next, take an arbitrary node and compute its degree (in \(\Theta(1)\) time), since the graph is represented as an adjacency list). If the degree is \(n - 1\), then the graph is a ``hub and spoke'' graph, and this is the hub.

If the degree is not \(n - 1\), but instead 1, this node might be a spoke. Check the degree of its neighbor as described above to see if its a hub.

If you see a degree that's neither 1 nor \(n - 1\), then the graph is not a ``hub and spoke'' graph.

Problem #249

Tags: lecture-10, graph theory

An undirected graph \(G = (V, E)\) has 23 nodes and 2 connected components. What is the smallest number of edges it can have?

Solution

21

Problem #250

Tags: lecture-10, connected components, graph theory

An undirected graph with 20 nodes and 30 edges has three connected components: \(A\), \(B\), and \(C\). Connected component \(A\) has 7 nodes. What is the smallest number of edges it can have?

Solution

6