• 20200921day17 刷题记录


    1 POJ1330 LCA模板

    2 洛谷LCA模板

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    #define INF 9999999
    using namespace std;
    struct node{
    	int to,next;
    }edge[500005<<1];
    int head[500005];
    int tot,cnt;
    int n,m,s;
    void add(int x,int y){
    	edge[++cnt].next=head[x];
    	edge[cnt].to=y;
    	head[x]=cnt;
    }
    int depth[500005],fa[500001][22],lg[50001];
    //depth表示每个节点的深度,fa[i][j]表示节点i的2^j级祖先
    //lg表示log_2(i)+1的值
    void fd(){
    	for(int i=1;i<=n;i++){//?
    		lg[i]=lg[i-1]+(1<<lg[i-1]==i);
    	}
    }
    void dfs(int now,int fath){
    	fa[now][0]=fath;
    	depth[now]=depth[fath]+1;
    	for(int i=1;i<=lg[depth[now]];i++){
    		fa[now][i]=fa[fa[now][i-1]][i-1];
    		//now的2^i祖先等于now的2^i-1祖先的2^i-1祖先
    		//2^i=2^i-1+2^i-1
    	}
    	for(int i=head[now];i;i=edge[i].next){
    		if(edge[i].to!=fath) dfs(edge[i].to,now);
    	}
    }
    int lca(int x,int y){
    	if(depth[x]<depth[y]) swap(x,y);//不妨设x深度>=y
    	while(depth[x]>depth[y]) x=fa[x][lg[depth[x]-depth[y]]-1];
    	//调到同一深度
    	if(x==y) return x;//二者重合 LCA就是x
    	for(int k=lg[depth[x]]-1;k>=0;k--){
    		//不断向上跳
    		if(fa[x][k]!=fa[y][k])
    			x=fa[x][k],y=fa[y][k];
    			//要跳到它们LCA的下面一层,所以肯定不相等,如果不相等就跳过去
    	}
    	return fa[x][0];//返回父亲节点
    }
    int main(){
    	scanf("%d%d%d",&n,&m,&s);
    	for(int i=1;i<=n-1;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		add(x,y);add(y,x);
    	}
    	fd();
    	dfs(s,0);
    	for(int i=1;i<=m;i++){
    		int x,y;
    		scanf("%d%d",&x,&y);
    		printf("%d
    ",lca(x,y));
    	}
    	return 0;
    }
    
    
    要做就做南波万
  • 相关阅读:
    为什么要用where 1=1?
    idea中.ignore忽略提交文件到Git的使用
    IDEA开发工具使用 git 创建项目、拉取分支、合并分支
    Linux常用命令及Linux系统根目录下各个目录的作用
    Xshell和Xftp的安装与使用教程
    Moco使用简单指导
    这样写会有什么问题呢?
    grunt学习笔记
    基于nginx的WebSocket反向代理
    maven依赖查找方法
  • 原文地址:https://www.cnblogs.com/liuziwen0224/p/20200921day16-001.html
Copyright © 2020-2023  润新知