Double connected components of undirected graphs
Point-Double connected graph : A connected undirected graph has no cut point inside, then the graph is a point-double connected graph.
Note: The outliers, and the 2.1 sides of the two graphs are point-to-double connected. Because they are all internal without cutting points.
Edge-Double connected graph : A connected undirected graph has no bridge inside, then the graph is edge-double connected.
Note: The outliers are edge-double connected, but the 2.1 sides are not edge-double connected.
By the above definition you can know: points-double connected graphs are not necessarily edge-double connected.
For an undirected graph, the point-to-double-connected maximal sub-graph is called the double-connected component. It is not difficult to find that each edge is exactly a two-connected component (so two points on one side is a point-a two-connected component). However, there may be a common point for different two-connected components, which proves that there is at most one common point for the different two-connected components, and it must be a top-cutting. On the other hand, arbitrary cutting tops are the common points of at least two different points-the two connected components.
The maximal sub-graph of edge-double connectivity is called the edge-double connected component. Except that the bridge does not belong to any side-two connected components, each of the other edges happens to belong to one edge-double connected component, and after all the bridges are removed, each connected component corresponds to an edge-double connected component in the original image.
in short:
Determine if a graph is a point-double-connected as long as you see if there are any cut points in the graph. (More stacks than looking for a cut.)
Determine if a graph is a side-double connected as long as you see if there is a bridge in the picture.
If you see there are still a lot of confusion, first draw to think about contradictions, and then see the code can be more clear, there are a lot of comments, if you have to look elsewhere to understand the algorithm of cutting points.
#include <cstdio>#include<cstring>#include<algorithm>#include<queue>#include<vector>#include<stack>using namespacestd;Const intmaxn= ++Ten;intn,m;intbcc_cnt;intDfs_clock;//bcc_cnt count A total number of points-two connected componentsintPRE[MAXN];//vis mark, which also marks the number of points in the treeBOOLISCUT[MAXN];intBCCNO[MAXN];//Bccno[i]=x indicates that the first vertex is a double connected component of X pointvector<int> G[MAXN],BCC[MAXN];//Bcc[i] Contains the I point-all nodes of the double connected componentstructEdge//structure of the Edge{ intu,v; Edge (intUintv): U (U), V (v) {}};stack<Edge>S;intDfsintUintFA) { intlowu=pre[u]=++Dfs_clock; intChild=0; for(intI=0; I<g[u].size (); i++) { intV=g[u][i];//Remove PointEdge e = Edge (U,V);//Create this Edge if(!pre[v])//V has not been visited{s.push (e); //put edge into stackchild++; intLowv=dfs (V,u);//ask for low firstlowu=min (LOWU,LOWV); if(LOWV >= Pre[u])//This node is a cutting point{Iscut[u]=true; Bcc_cnt++;//note bcc_cnt numbering starting from 1Bcc[bcc_cnt].clear ();//clear the left before while(true)//produces a double-connected component,{Edge x=s.top ();//remove the edges successivelyS.pop (); //a point may belong to more than one connected component, and it must be a cut point. if(bccno[x.u]!=bcc_cnt)//this point has not yet been counted to this connected component. {bcc[bcc_cnt].push_back (X.U); BCCNO[X.U]=bcc_cnt;//prevention of repetitive statistics } if(bccno[x.v]!=bcc_cnt) {Bcc[bcc_cnt].push_back (X.V); BCCNO[X.V]=bcc_cnt; } if(X.u==u && x.v==v)//sweep to U-v, the stack is not connected to u side. Keep trying other kids . Break; } } } Else if(V!=FA)//It's been visited on the top of the U.{s.push (e); //This is a double-connected component with U.lowu=min (lowu,pre[v]); } } /*the root of the child must be greater than 1 to be a cut point, there will be a cut point to have two connected components. (1) What if the root is not a cutting point? Assuming that the root is not a cutting point, then the root is at most 1 children, that is, the root is 1, then the root cannot be in any 1 double connected components. Assuming that the root is a cut point, each child is a connected component respectively. Then it will be processed as a double-link component in the code above. (2) What if there is a bridge? Like U-v is a bridge, so what? Suppose the u-v is a bridge, and you have a smaller timestamp in the number. V is a cut point, u-v after the disconnection, and V is connected to become a double connected components. When you go back to U, the stack (or top) does not have an edge that contains u until another connected component is generated. If you do not have a connecting component in your child, then the child connected to U must have an edge to the top of U, and they form a ring, and the two connected components are produced again, and the other cut points are resolved. */ if(fa<0&& child==1) iscut[u]=false; returnLowu;}voidFIND_BCC (intN) {memset (PRE,0,sizeof(pre)); memset (Iscut,0,sizeof(Iscut)); memset (Bccno,0,sizeof(BCCNO)); Dfs_clock= BCC_CNT =0; for(intI=0; i<n;i++)//to prevent multiple connected graphs, all of them need to be searched. if(!pre[i]) DFS (i,-1);}intMain () { while(SCANF ("%d%d", &n,&m) = =2&&N) { for(intI=0; i<n;i++) g[i].clear ();//Point Set for(intI=0; i<m;i++)//Input Edge { intu,v; scanf ("%d%d",&u,&v); G[u].push_back (v); G[v].push_back (U); } FIND_BCC (n); //calculate the number of two connected componentsprintf"Point-two connected components%d \ n", bcc_cnt); for(intI=1; i<=bcc_cnt;i++)//outputs each of the two connected components. Maybe point A is output in the first two-connected component, and it appears in the 2nd double-connected component because it is a cut point. {printf ("the first%d points-the two connected components contain the following points: \ n", i); Sort (&bcc[i][0],&bcc[i][0]+bcc[i].size ());//sort vectors so that the output point is small to large for(intj=0; J<bcc[i].size (); j + +) {printf ("%d", Bcc[i][j]); } printf ("\ n"); } } return 0;}
Annotated source code
The detailed explanation of the two connected components. (according to Rujia's training guide p314)