Graphs
Graphs
Graphs
Glossary.
The key method adj() allows client code to iterate through the
vertices adjacent to a given vertex. Remarkably, we can build all of the
algorithms that we consider in this section on the basic abstraction
embodied in adj().
We prepare the test data tinyG.txt, mediumG.txt, and largeG.txt,
using the following input file format.
GraphClient.java contains typical graph-processing code.
Graph representation.
Depth-first search.
Finding paths.
Breadth-first search.
Connected components.
The problems that we have solved with DFS are fundamental. Depth-
first search can also be used to solve the following problems:
Cycle detection: Is a given graph acyclic? Cycle.java uses
depth-first search to determine whether a graph has a cycle, and
if so return one. It takes time proportional to V + E in the worst
case.
Two-colorability: Can the vertices of a given graph be assigned
one of two colors in such a way that no edge connects vertices of
the same color? Bipartite.java uses depth-first search to
determine whether a graph has a bipartition; if so, return one; if
not, return an odd-length cycle. It takes time proportional to V + E
in the worst case.
Bridge: A bridge (or cut-edge) is an edge whose deletion
increases the number of connected components. Equivalently, an
edge is a bridge if and only if it is not contained in any
cycle. Bridge.java uses depth-first search to find time the
bridges in a graph. It takes time proportional to V + E in the worst
case.
Biconnectivity: An articulation vertex (or cut vertex) is a vertex
whose removal increases the number of connected components.
A graph is biconnected if it has no articulation
vertices. Biconnected.java uses depth-first search to find the
bridges and articulation vertices. It takes time proportional to V +
E in the worst case.
Planarity: A graph is planar if it can be drawn in the plane such
that no edges cross one another. The Hopcroft-Tarjan algorithm
is an advanced application of depth-first search that determines
whether a graph is planar in linear time.
Symbol graphs.
Exercises
3. Create a copy constructor for Graph.java that takes as input a
graph G and creates and initializes a new copy of the graph. Any
changes a client makes to G should not affect the newly created
graph.
26. Write
a SymbolGraph client DegreesOfSeparationDFS.java that
uses depth-first instead of breadth-first search to find paths
connecting two performers.
Creative Problems
32. Parallel edge detection. Devise a linear-time algorithm to
count the parallel edges in a graph.
Web Exercises
1. Find some interesting graphs. Are they directed or undirected?
Sparse or dense?
2. Degree. The degree of a vertex is the number of incident edges.
Add a method int degree(int v) to Graph that returns the degree of
the vertex v.
3. Suppose you use a stack instead of a queue when running
breadth-first search. Does it still compute shortest paths?
4. DFS with an explicit stack. Give an example of possibility of
stack overflow with DFS using the function call stack, e.g., line
graph. Modify DepthFirstPaths.java so that it uses an explicit
stack instead of the function call stack.
5. Perfect maze. Generate a perfect maze like this one
explore(x, y)
-------------
- Mark the current cell (x, y) as "visited."
- If no wall to north and unvisited, then explore(x, y+1).
- If no wall to east and unvisited, then explore(x+1, y).
- If no wall to south and unvisited, then explore(x, y-1).
- If no wall to west and unvisited, then explore(x-1, y).
You can also try out your program on this list of 6 letter words.
13. Faster word ladders. To speed things up (if the word list is
very large), don't write a nested loop to try all pairs of words to
see if they are adjacent. To handle 5 letter words, first sort the
word list. Words that only differ in their last letter will appear
consecutively in the sorted list. Sort 4 more times, but cyclically
shift the letters one position to the right so that words that differ
in the ith letter will appear consecutively in one of the sorted
lists.
Try out this approach using a larger word list with words of
different sizes. Two words of different lengths are neighbors if
the smaller word is the same as the bigger word, minus the last
letter, e.g., brow and brown.
14. Suppose you delete all of the bridges in an undirected
graph. Are the connected components of the resulting graph the
biconnected components? Answer: no, two biconnected
components can be connected through an articulation point.
Hint: find the diameter of the tree (the longest path between two
vertices) and return a vertex in the middle.
27. Diameter of a tree. Given a graph that is a tree (connected
and acyclic), find the longest path, i.e., a pair of vertices v and w
that are as far apart as possible. Your algorithm should run in
linear time.
Solution: Consider the graph consisting of the edges 0-1, 0-2, 1-2,
and 2-1, with vertex 0 as the source.
31. Matlab connected components. bwlabel() or bwlabeln() in
Matlab label the connected components in a 2D or kD binary
image. bwconncomp() is newer version.
32. Shortest path in complement graph. Given a graph G,
design an algorithm to find the shortest path (number of edges)
between s and every other vertex in the complement graph G'.
The complement graph contains the same vertices as G but
includes an edge v-w if and only if the edge v-w is not in G. Can
you do any better than explicitly computing the complement
graph G' and running BFS in G'?
33. Delete a vertex without disconnecting a graph. Given a
connected graph, design a linear-time algorithm to find a vertex
whose removal (deleting the vertex and all incident edges) does
not disconnect the graph.
Hint 1 (using DFS): run DFS from some vertex s and consider the
first vertex in DFS that finishes.
Hint 2 (using BFS): run BFS from some vertex s and consider any
vertex with the highest distance.
34. Spanning tree. Design an algorithm that computes a
spanning tree of a connected graph is time proportional to V +
E. Hint: use either BFS or DFS.
35. All paths in a graph. Write a program AllPaths.java that
enumerates all simple paths in a graph between two specified
vertices. Hint: use DFS and backtracking. Warning: there many
be exponentially many simple paths in a graph, so no algorithm
can run efficiently for large graphs.