• POJ


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

      

  • 相关阅读:
    flex布局简介
    未知宽高图片垂直居中
    网页设计中颜色应用
    webstorm10 注册码
    webapp尺寸
    【转】 svn 错误 以及 中文翻译
    css实现一个写信的格式
    使用::before和::after来完成尖角效果
    AI (Adobe Illustrator)详细用法(五)
    AI (Adobe Illustrator)详细用法(四)
  • 原文地址:https://www.cnblogs.com/lesning/p/14119392.html
Copyright © 2020-2023  润新知