Algorithm:
dfn [u] is the first visited u in dfs traversal.
low [u] is the depth of the ancestor with the earliest access time that the dfs u can reach.
First, we can get the dfn and low of each point by traversing the graph once.
Consider all points u and its son nodes s1,s2 in the dfs tree sk.
(1) If low [si] > = DFN [u] is satisfied for a certain si, then u is a cut point;
(2) If low [si] > DFN [u] is satisfied for a certain si, then the edge (u,si) is a bridge.
For the root node of the search tree, we need to make a special judgment: if the root has only one child node, then the root must not be the cut point.
Template:
const int MAX_V = 1000; const int MAX_E = 1000000; int vis[MAX_V]; //Node v's current access status, 0 indicates no access, 1 indicates in the stack, and 2 indicates that it has been accessed int dfn[MAX_V]; //Depth at which node v is accessed int low[MAX_V]; //The depth of the earliest ancestor that node v can reach bool cut[MAX_V]; bool bridge[MAX_V][MAX_V]; //Cur is the condition of cutting point: ① cur is the root and has more than one son; ② cur is not the root and has one son, V makes low [v] > = DFN [cur]; //(cur, i) is the condition of bridge: low [i] > DFN [cur]; void cut_bridge(int cur, int father, int dep, int n) //vertex: 0~n-1 { vis[cur] = 1; dfn[cur] = dep; low[cur] = dep; int children = 0; for(int i = 0; i < n; i++) { if(edge[cur][i]) //Node i connected to the current node { if(i != father && vis[i] == 1) //i in the current stack, it shows that there is a ring in the diagram, and the low value of cur is updated with the depth of i; { if(dfn[i] < low[cur]) low[cur] = dfn[i]; //Update the depth of the ancestor with the earliest access time that the node cur can reach to the depth when the node i is accessed; } if(vis[i] == 0) //I has not been visited, recursively accesses node i, and updates the low value of cur with the earliest reachable ancestor of I; { cut_bridge(i, cur, dep+1, n); children ++; if(low[i] < low[cur]) low[cur] = low[i]; if((father == -1 && children > 1) || (father == -1 && low[i] >= dfn[cur]) //Judgement cut point cut[cur] = true; if(low[i] > dfn[cur]) bridge[cur][i] = bridge[i][cur] = true; //Judgement Bridge } } } vis[cur] = 2; } //For each connected block, take a point X and call cut ˊ bridge (x, - 1,0, n), where n is the number of points.