POJ - 3694 Network
http://poj.org/problem?id=3694
q次询问,问你添加一条边后,图里还剩几个桥。
由于我热爱神仙数据结构,于是我用树链剖分过了这道题
做法:
1.并查集随便建树
2.不参与树的边加入q次询问,但不输出
3.树剖用0覆盖1,比如查询x---y的路径,就把x----y的路径点都覆盖成0,除了LCA(x,y);
具体看代码,很基础就是麻烦。。
#include<iostream> #include<cstring> #include<algorithm> #include<vector> #include<cstdio> #include<string> using namespace std; const int maxn = 1e5 + 11; vector<int>G[maxn]; void add(int be, int en) { G[be].push_back(en); } int n, m; int par[maxn]; struct Node { int ans, lazy; }tree[maxn * 4]; int find(int x) { if (par[x] == -1) return x; return par[x] = find(par[x]); } vector<pair<int, int> >ins; int top[maxn], fa[maxn], son[maxn], siz[maxn], dep[maxn]; int cnt, id[maxn]; int dfs(int x, int f, int d) { dep[x] = d; fa[x] = f; siz[x] = 1; int s = 0; for (int i = 0; i < G[x].size(); i++) { int p = G[x][i]; if (p == f) continue; dfs(p, x, d + 1); siz[x] += siz[p]; if (s < siz[p]) { s = siz[p]; son[x] = p; } } return 0; } int dfs2(int x, int t) { id[x] = ++cnt; top[x] = t; if (son[x] != 0) dfs2(son[x], t); for (int i = 0; i < G[x].size(); i++) { int p = G[x][i]; if (p == fa[x] || p == son[x]) continue; dfs2(p, p); } return 0; } //-------------------- int bulit(int node, int be, int en){ int mid = be + en >> 1; int l = node * 2; int r = node * 2 + 1; tree[node].lazy = -1; if (be == en) { tree[node].ans = 1; return 0; } bulit(l, be, mid); bulit(r, mid + 1, en); tree[node].ans = tree[l].ans + tree[r].ans; return 0; } int push(int node, int be, int en) { int mid = be + en >> 1; int l = node * 2; int r = node * 2 + 1; if (tree[node].lazy != -1) { tree[l].ans = (mid - be + 1)*tree[node].lazy; tree[r].ans = (en - mid)*(tree[node].lazy); tree[l].lazy = tree[r].lazy = tree[node].lazy; tree[node].lazy = -1; } return 0; } int update(int node, int be, int en, int LL, int RR, int val) { if (LL > RR) return 0; int mid = be + en >> 1; int l = node * 2; int r = node * 2 + 1; if (LL <= be && en <= RR) { tree[node].ans = val * (en - be + 1); tree[node].lazy = val; return 0; } push(node,be, en); if (LL <= mid) update(l, be, mid, LL, RR, val); if (RR > mid) update(r, mid + 1, en, LL, RR, val); tree[node].ans = tree[l].ans + tree[r].ans; return 0; } int change(int x, int y) { while (top[x] != top[y]) { if (dep[top[x]] < dep[top[y]]) swap(x, y); update(1, 1, n, id[top[x]], id[x], 0); x = fa[top[x]]; } if (dep[x] > dep[y]) swap(x, y); update(1, 1, n, id[x] + 1, id[y], 0); return 0; } int main() { int aaa = 0; while (~scanf("%d %d", &n, &m)) { if (n == m && n == 0) return 0; for (int i = 1; i <= n; i++) { par[i] = -1; G[i].clear(); siz[i] = 0; son[i] = 0; id[i] = 0; dep[i] = 0; fa[i] = 0; } cnt = 0; ins.clear(); for (int i = 1; i <= m; i++) { int be, en; scanf("%d %d", &be, &en); int a = find(be); int b = find(en); if (a == b) { ins.push_back(make_pair(be, en)); } else { par[a] = b; add(be, en); add(en, be); } } dfs(1, 0, 1); dfs2(1, 1); bulit(1, 1, n); for (int i = 0; i < ins.size(); i++) { int x = ins[i].first; int y = ins[i].second; change(x, y); } int q; scanf("%d", &q); printf("Case %d:\n", ++aaa); while (q--) { int x, y; scanf("%d %d", &x, &y); change(x, y); printf("%d\n", tree[id[1]].ans - 1); } printf("\n"); } return 0; }
寻找真正的热爱