1 2 3 4

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;
}

  

posted @ 2020-12-11 11:20  Lesning  阅读(71)  评论(0编辑  收藏  举报