HDU 2460 Network
Topic links
Test instructions: Given an empty graph, ask for an additional edge each time, ask how many bridges are left in the figure
Idea: the first double connected to the contraction point, and then form a tree, each time adding an edge, equivalent to ask the two-point path on how many edges, the tree chain split + line Tree processing
Code:
#include <cstdio> #include <cstring> #include <algorithm> #include <vector>using namespace std; #pragma COMMENT (linker, "/stack:1024000000,1024000000"); const int N = 100005;const int M = 200005;int N, m;struct Edge {in T u, V, Id;bool iscut; Edge () {}edge (int u, int v, int id) {this->u = u; this->v = v; this->id = id; this->iscut = false;}} Edge[m * 2], cut[m];int en, cn, first[n], next[m * 2];void init () {en = 0;memset (First,-1, sizeof (first));} void Add_edge (int u, int v, int id) {Edge[en] = Edge (U, V, id); Next[en] = first[u];first[u] = en++;} int pre[n], dfn[n], dfs_clock;void dfs_cut (int u, int fa) {Pre[u] = Dfn[u] = ++dfs_clock;for (int i = first[u]; i + 1; i = Next[i]) {if (edge[i].id = = FA) Continue;int v = edge[i].v;if (!pre[v]) {dfs_cut (V, edge[i].id);d fn[u] = min (Dfn[u], dfn[ V]), if (Dfn[v] > Pre[u]) {cut[cn++] = Edge[i];edge[i].iscut = Edge[i^1].iscut = true;}} else Dfn[u] = min (Dfn[u], pre[v]);}} void Find_cut () {cn = Dfs_clock = 0;memset (PRE,0, sizeof (pre)); for (int i = 1; I <= n; i++) if (!pre[i]) dfs_cut (i,-1);} Vector<int> G[n];int Bccno[n], bccn;void dfs_bcc (int u) {bccno[u] = bccn;for (int i = first[u]; i + 1; i = Next[i]) {if (edge[i].iscut) Continue;int v = edge[i].v;if (Bccno[v]) continue;dfs_bcc (v);}} void Find_bcc () {BCCN = 0;memset (bccno, 0, sizeof (BCCNO)), for (int i = 1; I <= n; i++) if (!bccno[i]) {bccn++;d fs_bcc (i) ;} for (int i = 1; I <= BCCN; i++) g[i].clear (); for (int i = 0; I < cn; i++) {int u = bccno[cut[i].u], v = bccno[cut[i] . V];g[u].push_back (v); G[v].push_back (U);}} int dep[n], fa[n], son[n], sz[n], top[n], id[n], idx;void dfs1 (int u, int f, int d) {dep[u] = D; sz[u] = 1; Fa[u] = f; son [U] = 0;for (int i = 0; i < g[u].size (); i++) {int v = g[u][i];if (v = = f) continue;dfs1 (V, u, D + 1); Sz[u] + = Sz[v];if (Sz[son[u]] < SZ[V]) son[u] = V;}} void dfs2 (int u, int tp) {Id[u] = ++idx; Top[u] = Tp;if (Son[u]) DFS2 (Son[u], TP); for (int i = 0; i < g[u].size (); i++) {int v = g[u][i];if (v = = fA[u] | | v = = Son[u]) continue;dfs2 (V, v);}} #define Lson (x) ((x<<1) +1) #define Rson (x) ((x<<1) +2) struct Node {int L, R, Sum, Flag;void Gao () {sum = 0;flag = 1;}} Node[n * 4];void Build (int l, int r, int x = 0) {node[x].l = l; node[x].r = r; node[x].flag = 0;node[x].sum = R-l + 1;if (L = = r) Return;int mid = (L + R)/2;build (L, Mid, Lson (x)); Build (mid + 1, R, Rson (x));} void pushup (int x) {node[x].sum = Node[lson (x)].sum + node[rson (x)].sum;} void pushdown (int x) {if (Node[x].flag) {Node[lson (x)].gao (); Node[rson (x)].gao (); node[x].flag = 0;}} int query (int l, int r, int x = 0) {if (node[x].l >= l && node[x].r <= r) {int ans = Node[x].sum;node[x].gao (); return ans;} Pushdown (x); int mid = (NODE[X].L + node[x].r)/2;int ans = 0;if (L <= mid) ans + = query (l, R, Lson (x)); if (R > Mid) Ans + = query (l, R, Rson (x));p ushup (x); return ans;} int Gao (int u, int v) {int TP1 = Top[u], TP2 = top[v];int ans = 0;while (TP1! = TP2) {if (DEP[TP1] < DEP[TP2]) {Swap (TP 1, TP2); SWAP (U, v);} Ans + = query (ID[TP1], id[u]); u = FA[TP1];TP1 = Top[u];} if (U = v) return ans;if (Dep[u] > Dep[v]) Swap (U, v), ans + = query (Id[son[u]], id[v]), return ans; int main () {int cas = 0;while (~scanf ("%d%d", &n, &m) && n | | m) {init (); int u, v;for (int i = 0; i < m ; i++) {scanf ("%d%d", &u, &v), Add_edge (U, V, i), Add_edge (V, U, i);} Find_cut (); find_bcc (); idx = 0;DFS1 (1, 0, 1);d FS2 (1, 1), int q;scanf ("%d", &q);p rintf ("Case%d:\n", ++cas); build (1, N) while (q--) {scanf ("%d%d", &u, &v); u = bccno[u]; v = BCCNO[V];CN = Gao (u, v);p rintf ("%d\n", CN);} printf ("\ n");} return 0;}
HDU 2460 Network (Dual connectivity + Tree chain split + segment tree)