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:
", ++aaa);
while (q--) {
int x, y;
scanf("%d %d", &x, &y);
change(x, y);
printf("%d
", tree[id[1]].ans - 1);
}
printf("
");
}
return 0;
}