Network
Time limit:5000ms Memory limit:65536k
Description
A network administrator manages a large network. The network consists of N computers and M links between pairs of computers. Any pair of computers is connected directly or indirectly by successive links, so data can is transformed between any of Computers. The administrator finds that some links is vital to the network, because failure of any one of the them can cause that data C An ' t is transformed between some computers. He call such a link a bridge. He is planning to add some new links one by one to eliminate all bridges.
The administrator by reporting the number of bridges in the network after each new link is added.
Input
The input consists of multiple test cases. Each test case is starts with a line containing, integers N (1≤n≤100,000) and M (n-1≤m≤200,000).
Each of the following M lines contains, integers a and B (1≤a≠b≤n), which indicates a link between computer A and B. Computers is numbered from 1 to N. It is guaranteed, that any, and computers is connected in the initial network.
The next line contains a single integer Q (1≤q≤1,000), which are the number of new links the administrator plans to ad D to the network one by one.
The i-th line of the following Q lines contains both integer A and B (1≤a≠b≤n), which is the i-th added new link conn Ecting computer A and B.
The last test was followed by a line containing the zeros.
Output
For each test case, print a line containing the test case number (beginning with 1) and Q lines, the i-th of which contain S a integer indicating the number of bridges in the network after the first I new links is added. Print a blank line after the output for each test case.
Sample Input
3 2
0 S
2 3
2
0 S
1 3
4 4
0 S
2 1
2 3
1 4
2
0 S
3 4
0 0
Sample Output
Case 1:
1
0
Case 2:
2
0
Source
Asia Hefei Regional Contest Online by USTC
Test Instructions : Gives an undirected connectivity graph, adding several edges, and the number of remaining bridges in the output graph after each additional edge.
idea : First is to run over the Tarjan algorithm, the number of bridges in the figure. When adding edges, such as adding a u->v edge, if the edge is part of an edge-connected component, it will not affect the bridge without adding it. But if it is not the same side of the two connected components, it will affect the nearest common ancestor of U and V to all the bridges on both the U and V roads, all of them are no longer bridges.
Now there is a tarjan+ +lca of the idea of shrinking points.
I don't have an online algorithm for LCA at the moment, but the Tarjan algorithm in the connected component is really a good thing. Using the DFN array generated by it, the LCA can be obtained directly. During DFS, each node is timestamp DFN according to the DFS sequence, and the parent node of each node is recorded.
In the Tarjan, if the same side of the two connected components to use and look up and set up, so that when the query can determine whether the same side of the two connected components.
If the components belong to a different component, the time-stamped nodes (for example, V) are merged one step at a time until the timestamp of V is on top of u, and then the U is merged up to U = v. At this point you are the LCA.
The merge process is reduced by 1 as soon as it encounters a bridge.
The code is as follows :
/* * ID:J.SURE.1 * PROG: * lang:c++ * *#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <ctime>#include <cmath>#include <stack>#include <queue>#include <vector>#include <map>#include <set>#include <string>#include <climits>#include <iostream>#define PB push_back#define LL Long Longusing namespace STD;Const intINF =0x3f3f3f3f;Const DoubleEPS =1e-8;/****************************************/Const intN =1e5+5, M =4e5+5;structEdge {intV, next; Edge () {} Edge (int_v,int_next): V (_v), Next (_next) {}}e[m];intN, m, deep, tot;intDfn[n], Head[n], fa[n], pre[n];intBridgevoidInit () {deep = tot = Bridge =0; for(inti =1; I <= N; i++) Fa[i] = i;memset(Head,-1,sizeof(head));memset(Pre,0,sizeof(pre));memset(DFN,0,sizeof(DFN));}intFind (intx) {if(x! = Fa[x])returnFA[X] = Find (fa[x]);returnx;}BOOLUnion (intXintY) {intFX = Find (x), FY = find (y);if(FX! = FY) {Fa[fy] = FX;return true; }return false;}voidAddintUintV) {E[tot] = Edge (V, Head[u]); Head[u] = tot++; E[tot] = Edge (U, Head[v]); HEAD[V] = tot++;}intDfsintUintPA) {intLowu = Dfn[u] = ++deep; for(inti = Head[u]; ~i; i = e[i].next) {intv = e[i].v;if(!dfn[v]) {Pre[v] = u;intLOWV = DFS (v, u); Lowu = min (Lowu, LOWV);if(Lowv > Dfn[u]) bridge++;ElseUnion (U, v);//If it's not a bridge, it belongs to the same side. Two Connected Components}Else if(Dfn[v] < Dfn[u] && v! = PA) {Lowu = min (Lowu, dfn[v]); } }returnLowu;}intLcaintUintV) {if(Find (u) = = Find (v))returnBridgeif(Dfn[u] > Dfn[v]) Swap (U, v); while(Dfn[u] < dfn[v]) {if(Union (Pre[v], v)) bridge--; v = pre[v]; }//From bottom to previous step along the father of V to merge until the common ancestor while(U! = V) {if(Union (U, Pre[u])) bridge--; U = pre[u]; }returnBridge;}intMain () {#ifdef j_sureFreopen ("000.in","R", stdin);//freopen ("999.out", "w", stdout);#endif intAa1 =1; while(scanf("%d%d", &n, &m), n| | m) {init ();intU, v; for(inti =0; I < m; i++) {scanf("%d%d", &u, &v); Add (U, v); } pre[1] =1; Dfs1,1);intOpscanf("%d", &op);printf("Case%d:\n", cas++); for(inti =0; I < op; i++) {scanf("%d%d", &u, &v);printf("%d\n", LCA (U, v)); }puts(""); }return 0;}
"Connected Graph | Edge Double connected component +tarjan+ and check set" POJ-3694 Network (400+MS)