What is a cut point? That is, the key point in the question. Remove a vertex from an undirected graph and the undirected graph will become multiple subgraphs. This vertex is called a cut vertex.
Similarly, the same is true for the cut edge. If an edge is removed and an undirected graph is converted into multiple subgraphs, this edge is called a cut edge and a bridge.
So how does Tarjan find a cut point?
If u is a cut point, and only if the following 1/2 is satisfied
1. If U is the root of a tree, u must have more than one subtree.
2. if u is not the root of a tree, (u, v) is the edge of a tree branch. When low [v]> = dfn [u.
The method for finding the cut point is clear. Condition 1 means that if it is the root, if there is only one subtree, that is, the entire graph is strongly connected, then remove the root node, it will certainly not become multiple subgraphs, so it will not become a cut point. Only when more than one subtree is removed from the root node can two or more subgraphs be created to become cut points.
Condition 2 is also easy to understand. If U is not a root, then u must have an ancestor. If low [v]> = dfn [u] exists, it indicates that the descendant of u can only access the ancestor of u through U. That is to say, if the descendant of U cannot access the ancestor of U without U, it is divided into at least two subgraphs, one is the U ancestor and the other is the descendant of the U.
However, I still don't understand why Tarjan is Min (low [u], low [I]) while min (low [u], dfn [I]); if Min (low [u], dfn [I]) is changed to min (low [u], low [I]); we can still find the strongly connected component, but if we change it when seeking the cut point, We Will wa. I still want to consult Daniel. Why is this subtle difference still unknown? It seems that graph theory is still not thoroughly understood,CodeYou have to back it up. It's boring to back up the code, understand it, and write it all. Thank you for your explanation!
Code
# Include <stdio. h> # include <stdlib. h> # include <string. h> # define Nmax 110 # define min (a, B) (a <B? A: B) # define max (A, B) (A> B? A: B) int map [Nmax] [Nmax]; int dfn [Nmax], low [Nmax]; bool isvisted [Nmax]; int gpoint [Nmax]; int index, root; int N, ans; void Tarjan (int u) {dfn [u] = low [u] = ++ index; isvisted [u] = true; for (INT I = 1; I <= N; ++ I) {If (Map [u] [I]) {If (! Isvisted [I]) {Tarjan (I); low [u] = min (low [u], low [I]); if (low [I]> = dfn [u] & U! = 1) // if it is not root {gpoint [u] ++;} else if (u = 1) // if it is root {root ++ ;}} else {LOW [u] = min (low [u], dfn [I]) ;}}} int main () {While (scanf ("% d ", & N) {int U, V; memset (MAP, 0, sizeof (MAP); memset (isvisted, false, sizeof (isvisted )); memset (gpoint, 0, sizeof (gpoint); ans = root = Index = 0; while (scanf ("% d", & U) {While (getchar ()! = '\ N') {scanf ("% d", & V); map [u] [v] = 1; Map [v] [u] = 1 ;}} tarjan (1); If (root> 1) {ans ++;} For (INT I = 2; I <= N; ++ I) {If (gpoint [I]) {ans ++ ;}} printf ("% d \ n", ANS) ;}return 0 ;}