Depth-first search marks a vertex when first reached, then recursively explores each still-unvisited neighbour before returning. To cover the whole graph, restart from every vertex not reached by earlier searches:For a directed graph, use outgoing neighbours; for an undirected graph, use both incidences of each edge. Each vertex is discovered once and each stored incidence is inspected once. Thus with adjacency lists the running time is and the visited information and recursion stack use space. An adjacency matrix representation instead requires scanning possible neighbours per visited vertex, giving time.
visit(v):
visited[v] = true
for w in adjacency[v]:
if not visited[w]:
visit(w)
for v in V:
if not visited[v]:
visit(v)In a bipartite graph, successive vertices along an edge lie in opposite parts. Following a cycle alternates parts at each step, so returning to the starting part requires an even number of edges. Thus a bipartite graph contains no odd cycle.
Conversely, choose a rooted spanning forest and colour each vertex by the parity of its depth in its component's tree. Suppose an edge had equally coloured endpoints. The unique tree path from to has lengthwhich is even. Adjoining makes an odd cycle. Therefore, if there are no odd cycles, every edge joins opposite colours, which supplies the required bipartition.This is the odd-cycle characterization of bipartite graphs. The argument applies separately to every connected component.
Augment depth-first search with a two-valued colour:Each tree edge receives opposite endpoint colours. If an inspected edge has equal colours, the preceding parity argument produces an odd cycle, so the graph is not bipartite. If the procedure succeeds, every edge has differently coloured endpoints, and the two colour classes are a bipartition. The outer loop handles disconnected graphs and isolated vertices.
paint(v, c):
colour[v] = c
for w in adjacency[v]:
if colour[w] is unset:
if not paint(w, 1-c):
return false
else if colour[w] == c:
return false
return true
for v in V:
if colour[v] is unset:
if not paint(v, 0):
return false
return trueEach vertex is coloured once and each edge incidence is checked once, giving time and extra space with adjacency lists. No separate cycle enumeration is required.
Articles by others on the same topic
There are currently no matching articles.