2
votes

Here are two excises about safe vertex deletions

5-28. An articulation vertex of a graph G is a vertex whose deletion disconnects G. Let G be a graph with n vertices and m edges. Give a simple O(n + m) algorithm for finding a vertex of G that is not an articulation vertex—i.e. , whose deletion does not disconnect G.

5-29. Following up on the previous problem, give an O(n + m) algorithm that finds a deletion order for the n vertices such that no deletion disconnects the graph. (Hint: think DFS/BFS.)


For 5-28, here is my thought:

I will just do a dfs, but not complete. The very first vertex which finished being processed will be a non-articulation vertex as it must be a leaf, or a leaf with a back edge pointing back to its ancestor (it is also not a articulation vertex).

For 5-29

I am not yet sure how to do it nicely. What comes into my mind is that in the graph, any vertex in a cycle can't deleted safely. Also, if there is no cycle, then deleting vertex backwards up from a dfs tree is also safe.

Could anyone give me some hints or tell me whether my thinking is correct or wrong?

3

3 Answers

2
votes

I think your solution to 5-28 is correct, it guarantees to find an node which is not articulation in O(n+m) time.

For 5-29, I think one way to do it is based on your solution to 5-28. While doing dfs, keep tract of when did each node leaves the stack(the time finished being processed). As you said, the one leaves first must be a leaf node so delete it will not disconnect the graph. Then you can delete the node leaves the stack secondly, it must also be a leaf node when we removed the first node. So we can delete the nodes in the reverse order of when they are popped from stack while doing DFS. Doing this only need one pass of DFS, thus running time is O(n+m).

Another simple way is to do it with BFS. For 5.28, deleting any node with maximum depth will not make the graph disconnect. Because each other nodes can be reached by a node with less depth. So for 5.29, we can delete all nodes by their sort depth in descending order. And also, we only need 1 BFS so the running time is O(n+m). I think it's easier for people to understand this approach.

0
votes

5-29: Expanding on your idea from 5-28, when you finish processing a vertex, it is a non-articulation vertex, so delete it. Then continue the DFS, and every time you finish processing another vertex, delete it too. Since you deleted the previous vertices that finished processing, every time you finish processing a vertex it is actually the first time you finish processing a vertex (for the graph without the previously deleted ones).

Another method, easier to prove, and a bit less efficient (but still O(V + E)) - Crete a DFS tree from the graph, then do topological sorting, then remove the vertices one by one starting from the last one in the sorted graph and moving back to the first one. At every step you remove the last one, and you know for sure (because it's a topological sorted graph) that it doesn't point to any other node, meaning no edges will be deleted except the edges leading to it. That means all other nodes are still reachable from the first node, and if the graph were bi-directional, then all nodes can reach the first node too, making it connected.

-1
votes

For the first problem, I will just delete the vertex you want to test from the graph and then run a DFS/BFS starting from any other vertex, counting the number of visited vertices. If it's less than (original size - 1), then the tested vertex is an articulation vertex.

Same idea applies to the second problem. You randomly pick a vertex and delete it, which will in general cut the graph into two blocks. If the deleted vertex is not an articulation vertex, then one of the two blocks must be empty. Otherwise, both blocks have some vertices, in which case, all vertices in BOTH blocks have to be listed in front of this vertex in the final "safe-deletion" order, while it is not important to decide which block to be completely removed first. So we can write a little recursive function like this:

vertex[] safe_order_cut (vertex[] v)
    if (v.length==0) return empty_vertex_list;
    vertex x = randomly_pick(v);
    vertex v1[], v2[];
    cut_graph(v,x,v1,v2);
    return safe_order_cut(v1) + safe_order_cut(v2) + x;

The connectivity problem (and related cut vertex problems) has been extensively studied in graph theory. If you are interested, you can read the wiki pages for more algorithms.