zoukankan      html  css  js  c++  java
  • quailty's Contest #1 道路修建 EXT(启发式合并)

    题目链接  道路修建 EXT

    考虑并查集的启发式合并,合并的时候小的子树的根成为大的子树的根的儿子。

    可以证明这样整棵树的深度不会超过$logn$。

    两个根合并的时候,产生的新的边的边权为当前的时间。

    那么询问的时候答案就为$x$到$y$的最短路径上的所有边的边权最大值。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    #define rep(i, a, b)	for (int i(a); i <= (b); ++i)
    #define dec(i, a, b)	for (int i(a); i >= (b); --i)
    
    const int N = 5e5 + 10;
    
    int T;
    int n, m;
    int num;
    int ans;
    int father[N], c[N], root[N], deep[N], sz[N];
    int now;
    unordered_set <int> s[N];
    
    int main(){
    
    	scanf("%d", &T);
    	while (T--){
    		scanf("%d%d", &n, &m);
    		num = n;
    		ans = 0;
    		rep(i, 0, n + 1){
    			s[i].clear();
    			s[i].insert(i);
    		}
    
    		rep(i, 1, n){
    			c[i] = 0;
    			sz[i] = 1;
    			father[i] = i;
    			deep[i] = 1;
    			root[i] = i;
    		}
    
    		rep(i, 1, m){
    			int op, x, y;
    			scanf("%d%d%d", &op, &x, &y);
    			x ^= ans;
    			y ^= ans;
    
    			if (op == 0){
    				if (root[x] == root[y]){
    					printf("%d
    ", ans = num);
    					continue;
    				}
    
    				--num;
    				int fx = root[x], fy = root[y];
    				if (sz[fx] < sz[fy]){
    					swap(fx, fy);
    					swap(x, y);
    				}
    
    				c[fy] = i;
    
    				sz[fx] += sz[fy];
    				father[fy] = fx;
    				sz[fy] = 0;
    				for (auto u : s[fy]){
    					root[u] = fx;
    					++deep[u];
    					s[fx].insert(u);
    				}
    
    				s[fy].clear();
    				printf("%d
    ", ans = num);			
    			}
    
    			else{
    				if (root[x] != root[y]){
    					printf("%d
    ", ans = 0);
    					continue;
    				}
    
    				now = 0;
    				if (deep[x] < deep[y]) swap(x, y);
    				while (deep[x] != deep[y]){
    					now = max(now, c[x]);
    					x   = father[x];
    				}
    
    				while (true){
    					if (x == y) break;
    					now = max(now, c[x]);
    					now = max(now, c[y]);
    					x = father[x];
    					y = father[y];
    				}
    
    				printf("%d
    ", ans = now);
    			}
    		}
    	}
    
    	return 0;
    }
    

      

  • 相关阅读:
    bzoj3996
    bzoj3157 3516
    bzoj1937
    bzoj1532
    bzoj3572
    bzoj1453
    bzoj3205
    bzoj2595
    关于高斯消元解决xor问题的总结
    linux查找和替换命令
  • 原文地址:https://www.cnblogs.com/cxhscst2/p/8605623.html
Copyright © 2011-2022 走看看