Definition:
For a connected graph, if any two points have at least two points do not repeat the path, it is said that the graph is a point double-connected (for short), if any two points there is at least two edges do not repeat the path, it is said that the graph is the edge of the two-connected . The definition of a point double connected graph is equivalent to any two edges being in a simple ring, while the definition of edge double connected graph is equivalent to any one edge in at least one simple ring. For an undirected graph, the maximal sub-graph of the point-double-connected is called the Point-double -connected component (the double-connected component), and the maximal sub-graph of the edge-double-connected is called the edge-connected component . This blog is to summarize the method of solving the two-connected component of undirected graph point and the double connected component of the edge.
algorithm:
In fact, the solution of the two-connected component and the edge-connected component is closely related to the solution of the cut point. At most, there is only one common point for the two connected components, that is, one cutting top, and any one cutting top is a common point with at least two points connected to each other. The two connected components of different sides have no common point, while the bridge is not in the two-connected component of any one side, the point double connected component must be a side double connected component.
The following first introduces the Tarjan algorithm of the point dual connected component :
In the previous blog, we already know how to solve the cut-off, it is easy to find that when we find the top of the cut, we have completed a single large double-connected sub-graph access, then if we are in the process of Dfs to save the traversed points, is it possible to get a point of the two connected components? In order to implement the algorithm, we can save the traversed edges with a stack in the process of solving the cutting top (note not!). since the different two-connected components have a common point that is cut-top ), then whenever a point is found a double connected component, that is, the child node V and the parent node U satisfies the relationship low[v]>=dfn[u], we will take the stack of things out until the current edge.
Note that in the stack is not the point, but the edge, this is because the point of the two connected components there is a repetition point, if we put in the stack is a point, then for some points of the two connected components, there will be less points (these points are cut-top).
Code:
structedge{intu,v; Edge (intu=0,intv=0): U (U), V (v) {}}E[MAXM];intN,M,STAMP,DFN[MAXN],LOW[MAXN],ISCUT[MAXN],BCCNO[MAXN];intScnt,stack[maxm],bcc_cnt;vector<int>VEC[MAXN],BCC[MAXN];voidTarjan (intIndexintFA) { intChild=0, TMP; Dfn[index]=low[index]=++Stamp; for(intI=0; I<vec[index].size (); i++) {tmp=e[vec[index][i]].v; if(!Dfn[tmp]) {stack[++scnt]=vec[index][i],child++; Tarjan (Tmp,index); Low[index]=min (low[index],low[tmp]); if(low[tmp]>=Dfn[index]) {Iscut[index]=1; bcc[++bcc_cnt].clear (); while(1) { intnum=stack[scnt--]; if(bccno[e[num].u]!=bcc_cnt) {Bcc[bcc_cnt].push_back (E[NUM].U); BCCNO[E[NUM].U]=bcc_cnt; } if(bccno[e[num].v]!=bcc_cnt) {Bcc[bcc_cnt].push_back (E[NUM].V); BCCNO[E[NUM].V]=bcc_cnt; } if(E[num].u==index && e[num].v==tmp) Break; } } } Else if(Dfn[tmp]<dfn[index] && tmp!=FA) {stack[++scnt]=Vec[index][i]; Low[index]=min (Low[index], dfn[tmp]); } } if(fa<0&& child==1) Iscut[index]=0;}voidfind_bcc () {//bccno value of cut top is meaninglessmemset (DFN,0,sizeof(DFN)); memset (Low,0,sizeof(low)); memset (Iscut,0,sizeof(Iscut)); memset (Bccno,0,sizeof(BCCNO)); Memset (BCC,0,sizeof(BCC)); Stamp=scnt=bcc_cnt=0; for(intI=1; i<=n;i++) if(!Dfn[i]) Tarjan (i,-1);
View Code
It is important to note that after the algorithm is over, each node will have a number that represents which point it belongs to, but the number of the cut-off is totally meaningless ! This algorithm uses two time stamps and stacks flexibly, and completes the discovery of the point double connected component.
Example: Uvalive 5135
Then we introduce the solution algorithm of the side double connected component :
The solution of the side double connected component is very simple, because there is no common edge between the two connected components, and the bridge is not in any one of the two connected components, so the algorithm is very simple, that is, DFS first found all the bridge, once again Dfs (excluding the bridge) to find the edge of the dual connectivity components.
PS: Of course, it can be implemented with DFS one time.
Code:
structedge{intu,v; Edge (intu=0,intv=0): U (U), V (v) {}}E[MAXM];intN,m,stamp,dfn[maxn],low[maxn],bccno[maxn],bcc_cnt;vector<int>VEC[MAXN],BCC[MAXN];BOOLG[MAXN][MAXN],ISBRIDGE[MAXM];voidTarjan (intIndexintFA) { inttmp; Dfn[index]=low[index]=++Stamp; for(intI=0; I<vec[index].size (); i++) {tmp=e[vec[index][i]].v; if(!Dfn[tmp]) {Tarjan (Tmp,index); Low[index]=min (low[index],low[tmp]); if(low[tmp]>Dfn[index]) isbridge[vec[index][i]=isbridge[vec[index][i]^1]=1; } Else if(Dfn[tmp]<dfn[index] && tmp!=FA) {Low[index]=min (Low[index], dfn[tmp]); } }}voidDfsintindex) {Dfn[index]=1; Bccno[index]=bcc_cnt; for(intI=0; I<vec[index].size (); i++) { inttmp=Vec[index][i]; if(Isbridge[tmp])Continue; if(!DFN[E[TMP].V]) {DFS (E[TMP].V); } }}voidfind_ebcc () {bcc_cnt=stamp=0; memset (DFN,0,sizeof(DFN)); memset (Low,0,sizeof(low)); memset (Isbridge,0,sizeof(Isbridge)); memset (Bccno,0,sizeof(BCCNO)); Memset (BCC,0,sizeof(BCC)); for(intI=1; i<=n;i++) if(!Dfn[i]) Tarjan (i,-1); memset (DFN,0,sizeof(DFN)); for(intI=1; i<=n;i++) { if(!Dfn[i]) {bcc_cnt++; DFS (i); } } }
View Code
POJ 3352
The so-called double connectivity and strong connectivity, the biggest difference is also the most essential difference is that the former applies to undirected graphs, and the latter is applicable to the graph
Two connected components (two connected components) of Tarjan three algorithms (reproduced)