zoukankan      html  css  js  c++  java
  • Hihocoder 最近公用祖先三 在线LCA

    在线的LCA算法,dfs遍历整棵树,对于每个点出现的时候都插入到数组中,然后查询两个点的lca就是两个点在数组中最后出现位置间的dep值最小的点,就转化为链上的RMQ问题了。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <set>
    #include <bitset>
    #include <queue>
    #include <stack>
    #include <string>
    #include <iostream>
    #include <cmath>
    #include <climits>
    
    using namespace std;
    const int maxn = 1e5 + 10;
    int head[maxn], nxt[maxn << 1], v[maxn << 1];
    int rpos[maxn], n, Q, cnt, ecnt;
    map<string, int> mp;
    map<int, string> smp;
    char name1[1024], name2[1024];
    
    struct Node {
    	int dep, id;
    	bool operator < (const Node &x) const {
    		return dep < x.dep;
    	}
    };
    
    Node val[maxn << 1], minv[maxn << 1][30];
    
    void adde(int uu, int vv) {
    	v[ecnt] = vv; nxt[ecnt] = head[uu]; head[uu] = ecnt++;
    }
    
    int getid(char *str) {
    	if(mp.count(str) == 0) {
    		int mpz = mp.size();
    		mp[str] = mpz + 1;
    		smp[mpz + 1] = str;
    		return mpz + 1;
    	}
    	return mp[str];
    }
    
    void dfs(int now, int fa, int dep) {
    	val[++cnt].dep = dep; val[cnt].id = now;
    	for(int i = head[now]; ~i; i = nxt[i]) if(v[i] != fa) {
    		dfs(v[i], now, dep + 1);
    		val[++cnt].dep = dep; val[cnt].id = now;
    	}
    	rpos[now] = cnt;
    }
    
    void initRMQ() {
    	for(int i = 1; i <= cnt; i++) {
    		minv[i][0] = val[i];
    	}
    	for(int j = 1; (1 << j) <= cnt; j++) {
    		for(int i = 1; i + (1 << j) - 1 <= cnt; i++) {
    			minv[i][j] = min(minv[i][j - 1], minv[i + (1 << (j - 1))][j - 1]);
    		}
    	}
    }
    
    Node query(int l, int r) {
    	int k = 0;
    	while((1 << (k + 1)) <= r - l + 1) k++;
    	return min(minv[l][k], minv[r - (1 << k) + 1][k]);
    }
    
    int main() {
    	memset(head, -1, sizeof(head));
    	scanf("%d", &n);
    	for(int i = 1; i <= n; i++) {
    		scanf("%s%s", name1, name2);
    		int a = getid(name1), b = getid(name2);
    		adde(a, b); adde(b, a);
    	}
    	dfs(1, -1, 0);
    	initRMQ();
    	scanf("%d", &Q);
    	while(Q--) {
    		scanf("%s%s", name1, name2);
    		int a = getid(name1), b = getid(name2);
    		a = rpos[a]; b = rpos[b];
    		if(a > b) swap(a, b);
    		Node ret = query(a, b);
    		puts(smp[ret.id].c_str());
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    CodeForces 288A Polo the Penguin and Strings (水题)
    CodeForces 289B Polo the Penguin and Matrix (数学,中位数)
    CodeForces 289A Polo the Penguin and Segments (水题)
    CodeForces 540C Ice Cave (BFS)
    网站后台模板
    雅图CAD
    mbps
    WCF学习-协议绑定
    数据库建表经验总结
    资源位置
  • 原文地址:https://www.cnblogs.com/rolight/p/4065995.html
Copyright © 2011-2022 走看看