Add an edge to the undirected graph of hdu4612 to minimize the number of bridges/scale in the undirected graph + calculate the diameter of the tree
The meaning of the question is as above, and contains a duplicate edge (if the duplicate edge is used, the two points can constitute an edge dual connection ).
First, reduce the point to a tree, and find the diameter of the number. The farthest link, the remaining side (BRIDGE) is naturally the least. Here we have learned the method of tree diameter: The first time we select any starting point U for bfs, to reach the farthest point v (level deepest), this point must be an endpoint of the tree's diameter ,, starting from this point, bfs, to the deepest point, the depth of this point is the diameter. (Proof: Assume that u is the diameter of a point, S, T is the diameter of the endpoint, set v! = T, then there is (V, U) + (U, S)> (T, U) + (U, S), conflict, so t = v; if u is not a point in diameter, set u to a point in diameter to x, which is also easy to prove.
The edge-diameter of the tree after the last point is reduced.
Let's talk about this time, ah, first stack explosion, without applying for space in C ++... The undirected graph tarjian is too unskillful! I haven't knocked on it for a long time ....
Note: In an undirected graph, the edges are connected and scaled down. You can do this:
Method 1: you must use the forward star to save the edge, and then mark the access edge (and mark the reverse edge at the same time. In this way, the word is naturally in an edge component. (The number of edges must be saved in an array! =-Father.
Method 2: the duplicate edge is regarded as a single side (only two points are not connected), without marking the edge. The father parameter is added. When the Back-to-parent side updates me, add a judgment! = Father.
# Pragma comment (linker, "/STACK: 10240000000000,102400000000000000") // apply for a space # include
# Include
# Include
# Include
# Include
# Include
Using namespace std; const int maxv = 300010; int dfn [maxv]; int low [maxv]; int visited [maxv]; int ins [maxv]; stack
Sta; int scc [maxv]; int times = 0; int block = 0; int n, m; int minn (int a, int B) {if (a <= B) return a; return B;} int nume = 0; int e [2000500] [2]; int head [maxv]; void inline adde (int I, int j) // source image {e [nume] [0] = j; e [nume] [1] = head [I]; head [I] = nume ++; e [nume] [0] = I; e [nume] [1] = head [j]; head [j] = nume ++;} int nume2 = 0; int newg [2000500] [2]; int head2 [maxv]; void inline adde2 (int I, int j) // new figure {newg [nume2] [0] = j; newg [nume2] [1] = head2 [I]; head2 [I] = nume2 ++; newg [nume2] [0] = I; newg [nume2] [1] = head2 [j]; head2 [j] = nume2 ++;} bool marke [2001000]; // access void tarjan (int u) {dfn [u] = low [u] = ++ times; ins [u] = 1; sta. push (u); for (int I = head [u]; I! =-1; I = e [I] [1]) {int child = e [I] [0]; if (marke [I]) continue; // put it here, otherwise the following will be updated and will not work. if (visited [child] = 0) {visited [child] = 1; marke [I] = marke [I ^ 1] = 1; // Mark Two-way tarjan (child); low [u] = minn (low [u], low [child]);} else if (ins [child]) {low [u] = minn (dfn [child], low [u]);} if (low [u] = dfn [u]) // The same side is connected to {block ++; int cur; do {cur = sta. top (); ins [cur] = 0; sta. pop (); scc [cur] = block;} while (cur! = U) ;}} void rebuild () {for (int I = 1; I <= n; I ++) // traverse all edges to recreate the graph, an edge exists if the same side is connected in a pair of connections. {For (int j = head [I]; j! =-1; j = e [j] [1]) {int ch = e [j] [0]; if (scc [I]! = Scc [ch]) adde2 (scc [I], scc [ch]) ;}} int lev[ maxv]; void bfsgetlev( int ss) // BFS layer {memset (lev, 0, sizeof (lev)); memset (visited, 0, sizeof (visited); queue
Q; q. push (ss); visited [ss] = 1; while (! Q. empty () {int cur = q. front (); q. pop (); for (int I = head2 [cur]; I! =-1; I = newg [I] [1]) {int vv = newg [I] [0]; if (! Visited [vv]) {lev[ vv] = lev[ cur] + 1; q. push (vv); visited [vv] = 1 ;}}return ;}void init () {block = times = 0; nume = 0; nume2 = 0; memset (marke, 0, sizeof (marke); memset (dfn, 0, sizeof (dfn); memset (low, 0, sizeof (low); memset (visited, 0, sizeof (visited); memset (head,-1, sizeof (head); memset (head2,-1, sizeof (head2);} int main () {while (scanf ("% d", & n, & m )! = EOF & (n | m) {init (); int a, B; for (int I = 0; I
Maxx) {maxx = lev[ I]; froms = I ;}} bfsgetlev( froms); // The farthest point (an endpoint of the straight diameter) for (int I = 1; I <= block; I ++) {if (lev[ I]> maxx) {maxx = lev[ I] ;}} ans = block-1-maxx; printf ("% d \ n", ans);} return 0 ;}