No cutting edge to cut the point of FIG.

definition:

  Given an undirected graph G = (V, E):

  For if after x∈V, deleting the node x and node x with all edges from the associated drawing, G is split into two sub FIG two or more unconnected, called G x is the cut point .

  For if after e∈E, omitted from FIG edge e, G is split into two disjoint sub-graphs, G e is called the bridge or the cutting edge.

Seeking:

  According to well-known computer scientist Robert Tarjan (yes, that Tarjan algorithm that LCA) named Tarjan algorithm can be obtained undirected graph point cut to the bridge of time online.

  Tarjan algorithm to no depth-first traversal of FIG.

Timestamp:

  In the process of FIG depth-first traversal in a chronological order for each node to be visited for the first time, given an integer of 1 to N nodes labeled N of the mark is called " time stamp " referred to dfn [x] .

Search tree:

  Optionally in the absence of a starting node to the drawing depth-first traversal, each access point only once. All edges (x, y) constituting a tree recursion occurred (depth-first traversal is used vis [x] array tags to prevent the edge side than the repeating walking), which we call " search undirected graph tree ", of course, generally no configuration to FIG undirected graph (not necessarily in communication) of the search tree of each block communication" search forest . "

Retroactive value:

  In addition to the timestamp, Tarjan algorithm also introduces a " retroactive value " low [x]. Provided subtree (x) represented by x is in the search tree in the subtree rooted. low [x] is defined as the minimum timestamp two nodes:

  1. Node (x) in the subtree.
  2. Through an edge not in the search tree, can reach subtree (x) in the node (the search tree is at x subtree rooted at the node is not connected to the edge of the search tree).

  To calculate Low [x], we first initialized to low [x] = dfn [x] (Logically root node are smaller than the timestamp in the timestamp subtree rooted in that node), and from the viewpoint of x All sides starting (x, y):

  1. If x is a parent node in the search tree of y, the other low [x] = min (low [x], low [y]).
  2. Without the side not in the search tree, the other low [x] = min (low [x], dfn [y]).

Cutting edge decision rule:

  Undirected edges (x, Y) is the cutting edge, if and only if x is a sub-tree search node y, satisfies:
                    DFN [x] <Low [Y]

Sufficiency:  

  By definition, dfn [x] <low [y] instructions from the subtree (y), without going through the premise edge (x, y) under that edge no matter go well beyond the reach x x or earlier than the access node after (if reached, the value should be traced> = dfn [x]), in other words, the deleted edges (x, y), subtree (y) connected to the x infinity, infinity is connected to the node accessed earlier than x Fig was fragmented into two parts, so (x, y) is the cutting edge.

necessity:

  If for any child node x, has dfn [x]> = low [y], the description of each subtree (y) can bypass the other edge nodes to access earlier than the arrival x or x, then (x, y) naturally is not cutting edge.

  Also, the cutting edge must be the search tree edge , and the edge in a simple ring must not cutting edge.

  Of particular note, as we go through it is nothing, so from every point x directed graph, total access to its parent fa. The edge part of the search tree calculation method of low (x, fa), and fa x node is not a child, it can not be used to update the timestamp low fa [x].
  However, if only the records of the parent node of each node, can not handle the case of multiple edges - When multiple edges between x and fa, (x, fa) of one side are not any cutting edge. In these repeating side, the only one considered "edge search tree", the other a few are not. Therefore, when there are multiple edges, dfn [fa] can be used to update the low [x].
  A good solution is: change record "recursively into each side of the node number" (This prevents access by searching the tree side fa capable of handling the heavy side). We use the adjacency list "paired transform" storage techniques to achieve this.

Attach Code:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int SIZE=100010;
 4 int head[SIZE],ver[2*SIZE],nxt[2*SIZE];
 5 int dfn[SIZE],low[SIZE],n,m,tot,num;
 6 bool bridge[SIZE*2];
 7 void add(int x,int y){
 8     ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;
 9 }
10 
11 void tarjan(intX, int in_edge) {
 12 is      DFN [X] = Low [X] ++ = NUM traced // initializes the value of the timestamp
 13 is      for ( int I = head [X]; I; I = NXT [I]) {
 14          int Y = Ver [I];
 15          IF (! DFN [Y]) {// search tree
 16              Tarjan (Y, I);
 . 17              Low [X] = min (Low [X], Low [Y]) ;
 18 is              IF (Low [Y]> DFN [X])
 . 19                  Bridge [I] = Bridge [I ^ . 1 ] = to true ;
 20 is          }
 21 is          the else  IF ! (I ^ = in_edge . 1) {// not in the search tree
 22 is              Low [X] = min (Low [X], DFN [Y]);
 23 is          }
 24      } 
 25  }
 26 is  
27  int main () {
 28      CIN >> >> n- m;
 29      TOT = . 1 ;
 30      for ( int I = . 1 ; I <= m; ++ I) {
 31 is          int X, Y;
 32          Scanf ( " % D% D " , & X, & Y);
 33 is          the Add (X, Y ), add (y, x) ; // not to store the pair of edges
 34 is      }
 35      for ( int= I . 1 ; I <= n-; ++ I) // for each undirected graph communication block
 36          IF ! (DFN [I]) Tarjan (I, 0 );
 37 [      for ( int I = 2 ; I < TOT; I + = 2 ) {
 38 is          IF (Bridge [I])
 39              the printf ( " % D% D \ n- " , Ver [I ^ . 1 ], Ver [I]);
 40      }
 41 is      return  0 ;
 42 is }

Point cut decision rule:

  If x is not a root node of the search tree (depth-first traversal starting point), then x is a cut point is present if and only if x is a sub-tree search node y, satisfies:
                  DFN [x] <= Low [Y]

  In particular, if x is a root node of the search tree, then x is such as to meet the presence of two child node if and only if the cutting edge.

  Proof is similar to the cutting edge.

  Because cutpoint determination rule number is less, so the cut point when the request is not necessary to consider the parent node and heavy side, a time stamp starting from all points x can be used to update the low [x].

Attach Code:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=20001,M=100001;
 4 int head[N],ver[2*M],nxt[2*M];
 5 int dfn[N],low[N];
 6 int n,m,tot,num,root;
 7 bool cut[N];
 8 
 9 void add(int x,int y){
10     ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;
11 }
12 
13 void Tarjan ( int X) {
 14      DFN [X] = Low [X] ++ = NUM;
 15      int In Flag = 0 ;
 16      for ( int I = head [X]; I; I = NXT [I]) {
 . 17          int Y = Ver [I];
 18 is          IF (! DFN [Y]) {
 . 19              Tarjan (Y);
 20 is              Low [X] = min (Low [X], Low [Y]);
 21 is              IF (Low [Y] > = DFN [X]) {
 22 is                  in Flag ++ ; // is the case to prevent the root node
 23 is                  IF (X = the root || in Flag>! . 1 )
 24                     cut[x]=true;
25             }
26         }else low[x]=min(low[x],dfn[y]);
27     }
28 }
29 
30 int main(){
31     scanf("%d%d",&n,&m);
32     tot=1;
33     for(int i=1;i<=m;++i){
34         int x,y;
35         scanf("%d%d",&x,&y);
36         if(x==y) continue;
37         add(x,y),add(y,x);
38     }
39     for(int i=1;i<=n;++i)
40         if(!dfn[i]) root=i,tarjan(i);
41     for(int i=1;i<=n;++i){
42         if(cut[i]) cout<<i<<" ";
43     }
44     return 0;
45 }

 

Guess you like

Origin www.cnblogs.com/Asika3912333/p/11372797.html