### UNDIRECTED GRAPHS STUDY GUIDE

**Graph representation.**
There are many possible internal representations of a graph. We discussed three.
You should be familiar with the tradeoffs.

- List of edges
- Adjacency matrix
- Adjacency lists

Usually, we use the adjacency-lists representation because most real-world graphs
are sparse.
**Important graph problems.** You should be familiar with
the following problems.

*Connectivity.* Is there a path between s and t?
- Cycle. Is there a cycle in the graph?
*Bipartiteness.* Is a graph bipartite?
*Euler cycle.* Is there a cycle that uses every edge exactly once?
*Hamilton cycle.* Is there a cycle that uses every vertex exactly once?
*Planarity.* Can the graph be drawn in the plane with no crossing edges?
(See this online game for a fun look at the problem.)
*Graph isomorphism.* Are two graphs the same graph (but with different vertex names)?

You should know how to solve the first three—not necessarily because these problems
are so important, but because you should have at least a few examples of
how to use DFS or BFS to solve problems.
For the last four, it's good scholarship to be know whether the problem is tractable
(polynomial time) and whether there exists an easy to understand tractable algorithm. We may
even ask you how these things on an exam. You do not need to be familiar with the details of
the best known algorithm for their solution.
One important meta-point is that there is no easy way to determine the complexity
of a graph problem. For example, finding an Euler cycle is solvable
in Θ(*E* + *V*) time
(and the algorithm is non-trivial but not hideously complex).
By contrast, finding a Hamilton cycle is an intractable problem.
Planarity can be solved in Θ(*E* + *V*) time,
but all known algorithms are extremely complex.
Graph isomorphism is particularly notable since its tractability has
remained elusive despite decades of research.

**Graph traversal.**

- DFS. You should know this algorithm absolutely cold by the time the exam comes around. For
example, you should be able to write
DepthFirstSearch.java
in your sleep, and the worst-case running time of
Θ(
*E* + *V*)
(using the adjacency-lists representation) should be scorched into your neurons.
- BFS. You should have the same level of familiarity as with DFS.
You should understand that almost any problem you care to solve with unweighted graphs can
be solved with one of these two algorithms. You should understand when each is appropriate to
use.

**Graph client design pattern (used for 4.1, 4.2, 4.3, and 4.4).**
Instead of creating bloated data types that both provide basic graph operations
*and* solve graph problems, we have one class
(e.g. `Graph`) that provides basic graph operations and many
special-purpose clients, each of which solves one graph problem
(e.g. `ConnectedComponents`).

### Recommended Problems

#### C level

- Textbook: 4.1.12

#### B level

- Textbook: 4.1.14, 4.1.10
- What is the running time for DFS or BFS if we use an adjacency matrix
insted of adjacency lists?

#### A level

- Textbook: 4.1.33