What is a graph ?
G=(V,E) V = a set of vertices E = a set of edges edge = unordered pair of vertices
What is a graph ? G=(V,E) V = {1,2,3,4,5} E = {{1,5}, {3,5}, {2,3}, {2,4}, {3,4}}
What is a graph ? G=(V,E) V = {1,2,3,4,5} E = {{1,5}, {2,3}, {2,4}, {3,4}}
Connectedness connected not connected How can we check if a graph is connected?
Representing a graph |V| * |V| symmetric matrix A with A i,j = 1 if {i,j} E A i,j = 0 otherwise adjacency matrix
Representing a graph adjacency matrix space = (V 2 )
Representing a graph adjacency matrix space = (V 2 ) is {u,v} an edge ? (?) list neighbors of v (?)
Representing a graph adjacency matrix space = (V 2 ) is {u,v} an edge ? (1) list neighbors of v (n)
Representing a graph adjacency lists for each vertex v V linked list of neighbors of v
Representing a graph adjacency lists space = (E) 1: 3,5 2: 3,4 3: 1,2,4 4: 2,3 5: 1
Representing a graph adjacency lists space = (E) 1: 3,5 2: 3,4 3: 1,2,4 4: 2,3 5: 1 is {u,v} an edge ? (?) list neighbors of v (?)
Representing a graph adjacency lists space = (E) 1: 3,5 2: 3,4 3: 1,2,4 4: 2,3 5: 1 is {u,v} an edge ? (min(d v,d u )) list neighbors of v (d v )
Representing a graph adjacency lists space = (E) 1: 3,5 2: 3,4 3: 1,2,4 4: 2,3 5: space = (V 2 ) adjacency matrix is {u,v} in E ? (min{d u,d v }) neigbors of v ? (d v ) is {u,v} in E ? (1) neigbors of v ? (n)
Counting connected components How can we check if a graph is connected? INPUT: graph G given by adjacency list OUTPUT: number of components of G
BFS (G,v) seen[v] true enqueue(Q,v) while Q not empty do w dequeue(Q) for each neighbor u of w if not seen[u] then seen[u] true enqueue(Q,u) G – undirected graph, V={1,...,n} seen[v] = false for all v V Q=queue (FIFO)
Counting connected components C 0 for all v V do seen[v] false for all v V do if not seen[v] then C++ BFS(G,v) output G has C connected components
DFS explore(G,v) visited[v] true for each neighbor u of v if not visited(u) then explore(G,u) G – undirected graph, V={1,...,n} visited[v] = false for all v V
DFS explore(G,v) visited[v] true pre[v] clock; clock++ for each neighbor u of v if not visited(u) then explore(G,u) post[v] clock; clock++ G – undirected graph, V={1,...,n} visited[v] = false for all v V
DFS explore(G,v) visited[v] true pre[v] clock; clock++ for each neighbor u of v if not visited(u) then explore(G,u) post[v] clock; clock++ vertex I v := [pre[v],post[v]] interval property for u,v V either * I v and I u are disjoint, or * one is contained in the other
DFS explore(G,v) visited[v] true pre[v] clock; clock++ for each neighbor u of v if not visited(u) then explore(G,u) post[v] clock; clock++ A B C D
DFS explore(G,v) visited[v] true pre[v] clock; clock++ for each neighbor u of v if not visited(u) then explore(G,u) post[v] clock; clock++ A B C D tree edges
Digraphs (directed graphs) G=(V,E) V = a set of vertices E = a set of edges edge = ordered pair of vertices u v (u,v)
Digraphs (directed graphs) adjacency lists for each vertex v V linked list of out-neighbors of v |V| * |V| matrix A with A i,j = 1 if (i,j) E A i,j = 0 otherwise adjacency matrix
a path = sequence of vertices v 1,v 2,...,v k such that (v 1,v 2 ) E,..., (v k-1,v k ) E Digraphs (directed graphs)
DAGs (acyclic digraphs) a cycle = sequence of vertices v 1,v 2,...,v k such that (v 1,v 2 ) E,..., (v k-1,v k ),(v k,v 1 ) E DAG = digraph with no cycle
Topological sort (linearization) INPUT: DAG G given by adjacency list OUTPUT: ordering of vertices such that edges go forward
DFS on digraphs explore(G,v) visited[v] true pre[v] clock; clock++ for each out-neighbor u of v if not visited(u) then explore(G,u) post[v] clock; clock++ G = digraph, V={1,...,n} visited[v] = false for all v V
DFS on digraphs A B C D
A B C D root descendant, ancestor child, parent
DFS on digraphs A B C D tree edge
DFS on digraphs A B C D tree edge
DFS on digraphs A B C D tree edge back edge
DFS on digraphs A B C D tree edge back edge cross edge
DFS on digraphs A B C D tree edge back edge cross edge forward edge
Relationships between the intervals? A B C D tree edge back edge cross edge forward edge
Topological sort using DFS Lemma: digraph is a DAG if and only if DFS has a back edge.
Topological sort using DFS Lemma: digraph is a DAG if and only if DFS has a back edge. explore(G,v) visited[v] true pre[v] clock; clock++ for each neighbor u of v if not visited(u) then explore(G,u) post[v] clock; clock++ Lemma: in a DAG every edge goes to a vertex with lower post
(strong) connectedness a digraph G is strongly connected if for every u,v V there exists a path from u to v in G
(strong) connectedness How to check if a digraph is strongly connected?
(strong) connectedness How to check if a digraph is strongly connected? for every u V do DFS(G,u) check if every v V was visited
(strong) connectedness How to check if a digraph is strongly connected? pick some u V DFS(G,u) check if every v V was visited DFS(reverse(G),u) check if every v V was visited
Strongly connected components DAG of strongly connected components
Strongly connected components Lemma: G and reverse(G) have the same strongly connected components.
Strongly connected components DAG of strongly connected components
Strongly connected components for all v V do color[v] white for all v V do if color[v]=white then DFS(reverse(G),v) DFS(G,u) (vertices in order post[])