Bo Main graph theory is weaker, search the template also will not use ...
So determined to learn the following Tarjan algorithm.
The concept of cutting and cutting edges is not redundant, and Tarjan can find cutting edges in linear time complexity.
Important concept: Time is a global variable clock records the time of the Access node. An undirected graph Dfs forms a forest, and when the graph has only one connected component, there is only one tree.
As in the no-map, except for the tree edges, the others are opposite edges. You can draw a picture to feel, can disprove, if there are other types of edge, then DFS along those side of the chart, then those side does not exist.
If the node is a root, then it is a necessary and sufficient condition for cutting points is that it has two sub-nodes.
Theorem
For other nodes, if the opposite edge of his sub-node does not point to its ancestor, then it is a cut point. The proof is obvious, because the non-graph is not across the edges of the subtree.
At the time of the specific judgment, the DFN value of low (U) is defined as the first ancestor of the U and its descendants, then the theorem can be converted to Low (v) >=pre (u). And if the descendants of V can only return to themselves, then the deletion (u,v) of an edge will allow the graph to be connected, then found the cutting edge (bridge).
Pseudo code
int dfs (int u,int FA) returns the low value of U, FA is the two access that is judged to be not the edge of the tree
{
Record the time and initialize the low value of U
Run Diagram {
If the child node V has not accessed {
DFS (v) and returns the descendant low value
Update the low value of U with descendant low value
If the low value of the descendant is >=pre//depending on whether the cut or cut point is required to replace the judging condition
So u is cut point//with array record, because a cut point, the condition may not be set up once
Otherwise, if it is a reverse edge//one. To satisfy the time of V is less than u, two. v is not the parent of U (two accesses to the side of the non-graph)
{
Update U's low value with reverse edge
}
}
Record low u with an array
return low U
}
For the root can be a special sentence, can be implemented by careful changes to the code, the practice is to record the number of child nodes, the original call FA assignment-1, plus a judge fa<0 and child = = 1 O'Clock iscut (u) = False
voidTarjan (intUintFA) {Dfn[u]= Low[u] = + +clock; for(inti = head[i]; ~i; i =Nxt[i]) { intv =To[i]; if(!Dfn[v]) {Tarjan (v,u); Low[u]=min (low[u],low[v]); if(Low[v] >Dfn[u]) {ans=min (Ans,wei[i])}}Else if(V! =FA) {Low[u]=min (low[u],dfn[v]); } }}
Look at some of the specific implementation of the code, there are some tips,
如果是用前向星存正反两条边是相邻并且奇偶性一定是不一样的,那么可以利用异或的开关性,来判断是不是树边
if
(i==(id^1))
continue
;
//不从i对应的边到父节点
Tarjan's study notes to cut edges and seek cutting points