• 备战NOIP——模板复习9


    这里只有模板,并不作讲解,仅为路过的各位做一个参考以及用做自己复习的资料,转载注明出处。

    最近公共祖先(LCA)

    树链剖分

    /*Copyright: Copyright (c) 2018
    *Created on 2018-10-28  
    *Author: 十甫
    *Version 1.0 
    *Title: LCA_树链剖分
    *Time: 8.5 mins
    */
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int maxn = 10005;
    
    int head[maxn];
    struct edge {
    	int to, next;
    } data[maxn * 2];
    inline void add_edge(int from, int to, int i) {
    	data[i] = (edge) {to, head[from]};
    	head[from] = i;
    }
    int depth[maxn], f[maxn], son[maxn], top[maxn], size[maxn];
    void dfs1(int pos, int d) {
    	size[pos] = 1, depth[pos] = d;
    	for(int i = head[pos];i;i = data[i].next) {
    		int u = data[i].to;
    		if(u == f[pos]) continue;
    		f[u] = pos;
    		dfs1(u, d + 1);
    		size[pos] += size[u];
    		if(size[u] > size[son[pos]]) son[pos] = u;
    	}
    }
    void dfs2(int pos, int t) {
    	top[pos] = t;
    	if(son[pos]) dfs2(son[pos], t);
    	for(int i = head[pos];i;i = data[i].next) {
    		int u = data[i].to;
    		if(u == f[pos] || u == son[pos]) continue;
    		dfs2(u, u);
    	}
    }
    int lca(int a, int b) {
    	while(top[a] != top[b]) {
    		if(depth[top[a]] < depth[top[b]]) swap(a, b);
    		a = f[top[a]];
    	}
    	return depth[a] > depth[b] ? b : a;
    }
    
    int main() {
    	int n;
    	scanf("%d", &n);
    	for(int i = 1;i < n;i++) {
    		int a, b;
    		scanf("%d%d", &a, &b);
    		add_edge(a, b, i), add_edge(b, a, i + n);
    	}
    	dfs1(1, 1);
    	dfs2(1, 1);
    	int q;
    	scanf("%d", &q);
    	while(q--) {
    		int a, b;
    		scanf("%d%d", &a, &b);
    		printf("%d
    ", lca(a, b));
    	}
    	return 0;
    }

    倍增

    /*Copyright: Copyright (c) 2018
    *Created on 2018-10-28  
    *Author: 十甫
    *Version 1.0 
    *Title: LCA_倍增
    *Time: 10 mins
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int size = 10005;
    const int maxk = 20;
    
    int head[size];
    struct edge {
    	int to, next;
    } data[size * 2];
    inline void add_edge(int from, int to, int i) {
    	data[i] = (edge) {to, head[from]};
    	head[from] = i;
    }
    int book[maxk][size], depth[size];
    void dfs(int pos, int d) {
    	depth[pos] = d;
    	for(int i = head[pos];i;i = data[i].next) {
    		int u = data[i].to;
    		if(u == book[0][pos]) continue;
    		book[0][u] = pos;
    		dfs(u, d + 1);
    	}
    }
    void make(int n) {
    	for(int k = 1;(1 << k) <= n;k++) {
    		for(int i = 1;i <= n;i++) {
    			book[k][i] = book[k - 1][book[k - 1][i]];
    		}
    	}
    }
    inline int lca(int a, int b) {
    	if(depth[a] < depth[b]) swap(a, b);
    	for(int k = maxk - 1;k >= 0;k--) {
    		if(depth[book[k][a]] >= depth[b]) {
    			a = book[k][a];
    		}
    	}
    	if(a == b) return a;
    	for(int k = maxk - 1;k >= 0;k--) {
    		if(book[k][a] != book[k][b]) {
    			a = book[k][a], b = book[k][b];
    		}
    	}
    	return book[0][a];
    }
    
    int main() {
    	int n;
    	scanf("%d", &n);
    	for(int i = 1;i < n;i++) {
    		int a, b;
    		scanf("%d%d", &a, &b);
    		add_edge(a, b, i), add_edge(b, a, i + n);
    	}
    	dfs(1, 1);
    	make(n);
    	int q;
    	scanf("%d", &q);
    	while(q--) {
    		int a, b;
    		scanf("%d%d", &a, &b);
    		printf("%d
    ", lca(a, b));
    	}
    	return 0;
    }
    NOIP 2018 RP++
  • 相关阅读:
    OSGI企业应用开发(八)整合Spring和Mybatis框架(一)
    error C2998:不能是模板定义的错误解决
    <Android 应用 之路> 干货集中营 ~ GankIOClient
    OSGI企业应用开发(七)细说Blueprint & Gemini Blueprint(二)
    C语言初学者代码中的常见错误与瑕疵(15)
    C语言初学者代码中的常见错误与瑕疵(14)
    C语言初学者代码中的常见错误与瑕疵(13)
    《C语言入门很简单》欢乐槽点
    为什么在我眼里你是一只傻逼——傻逼“常所用”句型之(2)——“当当网的就有XXX人评论,YYY%的推荐”
    踢爆IT劣书出版黑幕——由清华大学出版社之《C语言入门很简单》想到的(3)
  • 原文地址:https://www.cnblogs.com/Black-S/p/9886212.html
Copyright © 2020-2023  润新知