1. DFS框架
dfs(G,v)
Mark v as “discovered”.
For each vertex w that edge vw is in G:
If w is undiscovered:
dfs(G,w)
Otherwise:
“Check” vw without visiting w.
Mark v as “finished”.
int dfs(IntList[] adjVertices, int[] color, int v, …)
int w;
IntList remAdj;
int ans;
color[v]=gray;
<Preorder processing of vertex v>
remAdj=adjVertices[v];
while (remAdjnil)
w=first(remAdj);
if (color[w]==white)
<Exploratory processing for tree edge vw>
int wAns=dfs(adjVertices, color, w, …);
< Backtrack processing for tree edge vw , using wAns>
else
<Checking for nontree edge vw>
remAdj=rest(remAdj);
<Postorder processing of vertex v, including final computation of ans>
color[v]=black;
每个顶点只有三种状态:undiscovered、discovered but not finished、finished
2. BFS框架
Bfs(G,s)
Mark s as “discovered”;
enqueue(pending,s);
while (pending is nonempty)
dequeue(pending, v);
For each vertex w that edge vw is in G:
If w is “undiscovered”
Mark w as “discovered” and
enqueue(pending, w)
Mark v as “finished”;
3. 寻找联通片(Connected Components)
Input: a symmetric digraph G, with n nodes and 2m edges(interpreted as an undirected graph), implemented as a array adjVertices[1,…n] of adjacency lists.
Output: an array cc[1..n] of component number for each node vi
void connectedComponents(Intlist[ ] adjVertices,int n,int[ ] cc) // This is a wrapper procedure
int[ ] color=new int[n+1];
int v;
<Initialize color array to white for all vertices>
for (v=1; vn; v++)
if (color[v]==white)
ccDFS(adjVertices, color, v, v, cc);//Depth-first search
return
void ccDFS(IntList[ ] adjVertices, int[ ] color, int v, int ccNum, int[ ] cc)//v as the code of current connected component
int w;
IntList remAdj;
color[v]=gray;
cc[v]=ccNum;
remAdj=adjVertices[v];
while (remAdjnil)
w=first(remAdj);
if (color[w]==white)
ccDFS(adjVertices, color, w, ccNum, cc);
remAdj=rest(remAdj);
color[v]=black;
return
时间复杂度是 Θ(m+n)
4. 对于time的一些推论
- If w is a descendant of v in the DFS forest, then active(w)⊆active(v) , and the inclusion is proper if w≠v .
- If active(w)⊆active(v) , then w is a descendant of v. And if active(w)⊂active(v) , then w is a proper descendant of v. That is: w is discovered while v is active.
- If v and w have no ancestor/descendant relationship in the DFS forest, then their active intervals are disjoint.
- If edge
vw∈EG
, then
- vw is a cross edge iff. active(w) entirely precedes (在之前) active(v).
- vw is a descendant edge iff. there is some third vertex x, such that active(w)⊂active(x)⊂active(v) ,
- vw is a tree edge iff. active(w)⊂active(v) , and there is no third vertex x, such that active(w)⊂active(x)⊂active(v) ,
- vw is a back edge iff. active(v)⊂active(w) ,
5. White Path Theorem
w is a descendant of v in a DFS tree iff. at the time v is discovered(just to be
changing color into gray), there is a path in G from v to w consisting entirely of white vertices.