Finding the joint point of a graph without direction
Dfn[] Number of depth to save points
In a depth-first search tree, if you and V are two vertices, and you are the ancestor of V in the spanning tree, you must have DFN[U]<DFN[V], indicating that u is first accessed.
Back Edge : The original image in addition to the edge of the Dfs tree, and some side called back edge, such as: 1->2,1->3,2->3, Dfs 1->2->3, where the side of the Dfs tree is 1->2,2->3, then 1- >3 is the back side;
(1) If point U is the root of the DFS spanning tree, then you have at least 2 children. Reason: Because of the deletion of U, its children are located in the subtree is disconnected.
(2) If the point U is not the root of the DFS spanning tree, then a child of U, W, departs from the descendants of W or W or returns to the ancestor of U. If you can get there, then point U is not the joint point.
Therefore, you can set a new array low[for each store V to hold the lowest depth number that can be reached by V.
low[v]=min{
Dfn[u]
Min (Low[w]|w for the descendants of Point V)
Min (dfn[x]|x and v form back edges)
};
Therefore, the necessary and sufficient condition for vertex u is the joint point: when u is the root node, there are 2 or more children. U is not the root node when it's a child W, has low[w]>=dfn[u].
Low[w]>=dfn[u] Represents the child w of the vertex U, which is able to reach a minimum depth number greater than or equal to the vertex u depth number. And W's children do not exist without the side pointing to the U ancestor. This is a subtree that removes vertex u,u from the Dfs tree.
If the midpoint 6 is the joint point, because the child node of Point 6 low[w]>=dfn[u], and there is no back side that can point to the U ancestor. After you delete point 6, the subtree disconnects.
and point 7 is not the joint point, because Point 7 of the Children node 8, there is a back side, meet Low[8]<dfn[7],
After you delete point 7, the subtree is not fractured.
poj1523
1#include <stdio.h>2#include <string.h>3 intmap[1003][1003];4 intvis[1003];//Mark5 intdfn[1003];//to save the number of depths in his Dfs tree6 intDepth//Depth7 intsubnets[1003]//how much of the rest can be connected after deleting the point8 intNodenum;//Number of points9 intSon//number of children in root nodeTen intlow[1003];//the minimum number of depths to be reached. One voidInin () A { - inti,j; -memset (Vis,0,sizeof(Vis)); thememset (Subnets,0,sizeof(subnets)); -Depth=1;//start at depth of 1 -low[1]=dfn[1]=1;//The root node has a depth of 1. -son=0; +vis[1]=1; - } + intMinintXinty) A { at returnX<y?x:y; - } - voidDfsintu) - { - inti,j; - for(i=1; i<=nodenum;i++) in { - if(Map[u][i])//If two points are connected to { + if(!vis[i])//if it was previously accessed, that is not the back edge - { thevis[i]=1; *depth++;//depth +1 $dfn[i]=low[i]=depth;//UpdatePanax NotoginsengDFS (i);//Continue search -Low[u]=min (Low[u],low[i]);//Low[i] has been updated in the previous DFS, low[] can reach the lowest depth number, so to compare it itself and its children the if(Low[i]>=dfn[u])//If the node is a joint point + { A if(u==1) son++;//if it's a root node, son records a couple of children . the if(u!=1) subnets[u]++;//if it is not a root node, how many connected * components are there after the update is deleted? + } - } $ Else//if it has been previously visited, it indicates that there is a loop $ { -Low[u]=min (Low[u],dfn[i]);//Update low[] - } the } - }Wuyi } the intMain () - { Wu inti,j,u,v,flag,ff=1; - while(1) About { $ //Input Section -nodenum=0; -memset (Map,0,sizeof(map)); -scanf"%d",&u); A if(u==0) Break; +scanf"%d",&v); the if(V>nodenum) nodenum=v; - if(U>nodenum) nodenum=u; $map[u][v]=map[v][u]=1; the while(1) the { thescanf"%d",&u); the if(u==0) Break; -scanf"%d",&v); in if(V>nodenum) nodenum=v; the if(U>nodenum) nodenum=u; themap[u][v]=map[v][u]=1; About } the //Initialize the Inin (); the +Dfs1);//Achievements - if(son>1)//If the root node is a joint point the {Bayisubnets[1]=son-1;//Update subnets[1], that is, the number of children at the joint point the } the - if(ff>1) -printf"\ n"); theprintf"Network #%d\n", ff++); the theflag=0; the for(i=1; i<=nodenum;i++) - { the if(Subnets[i])//if the connected component is present, it indicates that the point joint point the { theflag=1;94printf"SPF node%d leaves%d subnets\n", i,subnets[i]+1);//Subnets[]+1 is because there are two pieces, a point; the } the } the if(!flag)98printf"No SPF nodes\n"); About } -}
View Code
Tarjan algorithm to find joint points