Calculate the bridge, scale down the point, LCA, and duplicate edges, and then add Q edges. After each addition, ask about the number of bridges... I personally think it is quite troublesome...
N vertices and M edges are given to ensure that all vertices are connected. There are duplicate edges in the data, and then Q edges are added. After each addition, an integer is output to represent the number of remaining bridges in the graph.
First, find out all the bridges, delete the bridges, contract the dual-connected components, connect these points with the bridges, and then process them with LCA.
For each newly added edge, first determine the Indented vertices at both ends and set them to u and v respectively.
The bridge to be eliminated by this edge must be a bridge on the two roads [LCA (u, v), u] and [LCA (u, v), v.
# Include
# Include
# Include
# Include
# Include
# Include
# Include # define LL long # define PI (acos (-1.0) # define EPS (1e-10) using namespace std; const int MAXN = 100010; struct N {int v, next;} Edge [MAXN * 4], Lca_Edge [MAXN * 4]; struct E {int u, v;} Bridge [MAXN * 2]; int Top_Edge, Top_Bridge, Lca_Top_Edge, lca_Time; int head [MAXN]; int Lca_Head [MAXN]; int mv [MAXN]; int depth [MAXN]; int Lca_Depth [MAXN]; int Lca_Vis [MAXN]; int Point [MAXN * 2]; int st [MAXN * 8]; int father [MAXN]; int Root [MAXN]; bool Cut [MAXN]; void link (int u, int v) {Edge [++ Top_Edge]. v = v; Edge [Top_Edge]. next = head [u]; head [u] = Top_Edge;} void Lca_Link (int u, int v) {Lca_Edge [++ Lca_Top_Edge]. v = v; Lca_Edge [Lca_Top_Edge]. next = Lca_Head [u]; Lca_Head [u] = Lca_Top_Edge;} int Find (int x) {while (x! = Father [x]) x = father [x]; return x;} void Merge (int u, int v) {int fu = Find (u ); int fv = Find (v); if (fu! = Fv) {father [fu] = fv ;}} int Dfs (int s, int f, int h) {mv [s] = 1; // indicates gray, that is, DFS has started and is waiting for backtracking depth [s] = h; int p, Temp_Depth, Min_Depth = MAXN; bool Cover = false; for (p = head [s]; p! =-1; p = Edge [p]. next) {if (Edge [p]. v! = F | Cover) {if (mv [Edge [p]. v] = 0) {Temp_Depth = Dfs (Edge [p]. v, s, h + 1); if (Temp_Depth <Min_Depth) Min_Depth = Temp_Depth;} else if (mv [Edge [p]. v] = 1) {if (depth [Edge [p]. v] <Min_Depth) Min_Depth = depth [Edge [p]. v] ;}} else Cover = true;} if (f! =-1 & Min_Depth> = depth [s]) {Bridge [Top_Bridge]. u = f; Bridge [Top_Bridge]. v = s; Top_Bridge ++;} else if (f! =-1) {Merge (f, s);} return Min_Depth;} void Lca_Dfs (int s, int h) {Lca_Depth [s] = h; point [Lca_Time] = s; Lca_Vis [s] = Lca_Time ++; for (int p = Lca_Head [s]; p! =-1; p = Lca_Edge [p]. next) {if (Lca_Vis [Lca_Edge [p]. v] =-1) {root [Lca_Edge [p]. v] = s; Cut [Lca_Edge [p]. v] = false; Lca_Dfs (Lca_Edge [p]. v, h + 1); Point [Lca_Time ++] = s ;}}} void Init_St (int site, int l, int r) {if (l = r) {st [site] = Lca_Depth [Point [l]; return;} int mid = (l + r)> 1; Init_St (site <1, l, mid); Init_St (site <1 | 1, mid + 1, r); if (st [site <1] <st [site <1 | 1]) st [site] = st [site <1]; else st [Site] = st [site <1 | 1];} int Query_St (int site, int L, int R, int l, int r) {if (l = L & R = r) {return st [site];} int mid = (L + R)> 1; if (mid <l) {return Query_St (site <1 | 1, mid + 1, R, l, r);} else if (r <= mid) {return Query_St (site <1, l, mid, l, r);} int h1 = Query_St (site <1, L, mid, l, mid ); int h2 = Query_St (site <1 | 1, mid + 1, R, mid + 1, r); return (h1