ACM Templates
Point double Connected Branch
Remove the bridge, the rest of the connected branches are the side of the two connected branches. If a connected graph with a bridge is to become a double connected graph, the double connected sub-graph is shrunk to a point, forming a tree. The side to be added is (leaf+1)/2 (leaf is the number of leaf nodes).
Refer to the topic Link:
POJ 3177 Redundant Paths
Given a connected undirected graph G, it is necessary to add at least a few edges to make it a double-connected graph.
Const intMAXN =5010;//PointsConst intMAXM =20010;//number of sides, because it is a no-map, so this valuestructedge{intTo, next;BOOLCut//Whether it is a bridge marker}EDGE[MAXM];intHEAD[MAXN], tot;intLOW[MAXN], DFN[MAXN], STACK[MAXN], BELONG[MAXN];the value of the//belong array is 1~blockintIndex,top;intBlock//Side double connected block numberBOOLINSTACK[MAXN];intBridge//Number of bridgesvoidAddedge (intUintV) {edge[tot].to = v; Edge[tot].next = Head[u]; edge[tot].cut=false; Head[u] = tot++;return;}voidTarjan (intUintPre) {intV Low[u] = dfn[u] = ++index; stack[top++] = u; Instack[u] =true; for(inti = Head[u]; I! =-1; i = edge[i].next) {v = edge[i].to;if(v = = Pre) {Continue; }if(! Dfn[v]) {Tarjan (V, u);if(Low[u] > Low[v]) {Low[u] = Low[v]; }if(Low[v] > Dfn[u]) {bridge++; Edge[i].cut =true; edge[i^1].cut =true; } }Else if(Instack[v] && low[u] > Dfn[v]) {Low[u] = Dfn[v]; } }if(Low[u] = = Dfn[u]) {block++; Do{v = stack[--top]; INSTACK[V] =false; BELONG[V] = block; } while(V! = u); }return;}voidInit () {tot =0;memset(Head,-1,sizeof(head));return;}intDU[MAXN];//indent to form a tree, the degree of each pointvoidSolveintN) {memset(DFN,0,sizeof(DFN));memset(Instack,false,sizeof(Instack)); Index = top = block =0; Tarjan (1,0);intAns =0;memset(Du,0,sizeof(du)); for(inti =1; I <= N; i++) { for(intj = Head[i]; J! =-1; j = edge[j].next) {if(Edge[j].cut) {du[belong[i]]++; } } } for(inti =1; I <= block; i++) {if(du[i]==1) {ans++; } }//Find the number of leaf nodes ans, the structure of two connected graphs need to add edge (ans+1)/2 printf("%d\n", (ans +1) /2);}intMain () {intN, M;intU, v; while(scanf("%d%d", &n, &m) = =2) {init (); while(m--) {scanf("%d%d", &u,&v); Addedge (U,V); Addedge (V,u); } solve (n); }return 0;}
Edge Double Connected Branch
For the point double connected branch, in fact in the process of finding a cut point can be in the way of each point two connected branches to find out. Create a stack that stores the current two connected branches and, when searching for a graph, adds the edge to the stack by finding a branch or back edge (not a cross-border). If a DFS (U) <=low is encountered at some time, it means that U is a cut point, and the edges are removed from the top of the stack at the same time, until an edge (U,V) is encountered, and the points that are taken out of these edges are connected to each other, forming a point-double-connected branch. A cut point can belong to multiple points of two connected branches, and the remaining points and each edge belong to and belong to only one point double connected branch.
Refer to the topic Link:
POJ 2942 Knights of the Round Table
Odd-circle, binary-graph-judging staining method, finding points of double connected branches
/ * * POJ 2942 Knights of the Round table * King Arthur will convene a Knights ' meeting at the round table, in order not to provoke a clash between the Knights, * and to enable the meeting to have satisfactory results, before each meeting must be for the Knights to attend the meeting to * 1. Two knights who hated each other could not sit directly adjacent to the 2 positions; * 2. The number of Knights present at the meeting must be odd, so that the vote will have a result. * Note: 1, the hatred given by the relationship must be two-way, there is no one-way hatred relationship. * 2, due to the round table, there must be just 2 knights in each of the Knights present. * That is, each knight's seat must have a knight on each side. * 3, a knight can not meet, that is, at least 3 knights can meet. * First, based on the given figure of mutual hatred to get a complement map. * Then it is the equivalent of finding points that cannot form a singular circle. * Use the following two theorems: * (1) If some vertices within a two-connected component are in a singular circle (that is, the two connected components contain odd loops), then the other vertices of the two connected components are also in some odd circles; * (2) If a double-connected component contains odd loops, then he must not be a binary graph. In turn, this is a necessary and sufficient condition. * So the way to do this is to find a double connected component of the complement map. Then for the point of the two connected components, using the staining method to determine whether it is a binary graph, not a binary graph, the point of the two connected components can exist * /Const intMAXN =1010;Const intMAXM =2000010;structedge{intTo, next;} EDGE[MAXM];intHEAD[MAXN], tot;intLOW[MAXN], DFN[MAXN], STACK[MAXN], BELONG[MAXN];intIndex,top;intBlocknumber of two connected components//pointsBOOLINSTACK[MAXN];BOOLCAN[MAXN];BOOLOK[MAXN];//MarkintTMP[MAXN];//temporarily store points in dual-connected componentsintcc//TMP countintCOLOR[MAXN];//DyeingvoidAddedge (intUintV) {edge[tot].to = v; Edge[tot].next = Head[u]; Head[u] = tot++;return;}BOOLDfsintUintCol//Stain Judging two-point diagram{Color[u] = col; for(inti = Head[u]; I! =-1; i = edge[i].next) {intv = edge[i].to;if(!ok[v]) {Continue; }if(Color[v]! =-1) {if(Color[v]==col) {return false; }Continue; }if(!dfs (V,!col)) {return false; } }return true;}voidTarjan (intUintPre) {intV Low[u] = dfn[u] = ++index; stack[top++] = u; Instack[u] =true; for(inti = Head[u]; I! =-1; i = edge[i].next) {v = edge[i].to;if(v = = Pre) {Continue; }if(! Dfn[v]) {Tarjan (V, u);if(Low[u] > Low[v]) {Low[u] = Low[v]; }if(Low[v] >= Dfn[u]) {block++;intVn CC =0;memset(OK,false,sizeof(OK)); Do{vn = Stack[--top]; BELONG[VN] = block; INSTACK[VN] =false; OK[VN] =true; Tmp[cc++] = vn; } while(VN!=V); Ok[u] =1;memset(Color,-1,sizeof(color));if(!dfs (U,0)) {Can[u] =true; while(cc--) {CAN[TMP[CC]] =true; } } } }Else if(Instack[v] && low[u] > Dfn[v]) {Low[u] = Dfn[v]; } }}voidSolveintN) {memset(DFN,0,sizeof(DFN));memset(Instack,false,sizeof(Instack)); Index = block = top =0;memset(CAN,false,sizeof(can)); for(inti =1; I <= N; i++) {if(! Dfn[i]) {Tarjan (I,-1); } }intans = n; for(inti =1; I <= N; i++) {if(Can[i]) {ans--; } }printf("%d\n", ans);}voidInit () {tot =0;memset(Head,-1,sizeof(head));}intG[MAXN][MAXN];intMain () {intN, M;intU, v; while(scanf("%d%d", &n, &m) = =2) {if(n = =0&& m = =0) { Break; } init ();memset(g,0,sizeof(g)); while(m--) {scanf("%d%d", &u, &v); G[U][V] = G[v][u] =1; } for(inti =1; I <= N; i++) { for(intj =1; J <= N; J + +) {if(I! = J && g[i][j] = =0) {Addedge (i, j); }}} solve (n); }return 0;}
Dual connected Branches