• HDOJ2586 最近公共祖先模板


    原题链接:HDOJ2586

    解析:用树上倍增法来求LCA

    代码实例:

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    #include<cstring>
    using namespace std;
    const int maxn = 40010;
    int f[maxn][20],d[maxn],Dist[maxn];
    //依次为:f[i,k]节点i上升2^k次方的节点,d[i]i的深度,Dist[i]i到树根的距离 
    int deep;//树的最大深度 
    vector<int> G[maxn];//来存放每个点相连的边的编号 
    struct Edge{
    	int from,to,dist;
    };
    vector<Edge> edges;
    void add_edge(int from,int to,int dist){//如果无向边压入两次 
    	edges.push_back(Edge{from,to,dist});
    	int m = edges.size()-1;
    	G[from].push_back(m);
    }
    void bfs(){//预处理 
    	queue<int> q;
    	q.push(1);
    	d[1] = 1;
    	while(!q.empty()){
    		int x = q.front();
    		q.pop();	
    		for(int i = 0;i < G[x].size();i++){
    			Edge& e = edges[G[x][i]];
    			if(d[e.to])	continue;
    			d[e.to] = d[x] + 1;
    			Dist[e.to] = Dist[x] + e.dist;
    			f[e.to][0] = x;
    			for(int j = 1;j < deep;j++)
    				f[e.to][j] = f[f[e.to][j-1]][j-1];
    				//e.to向上走2^k步到达的节点等于e.to向上走2^(k-1)步到达的节点再向上走2^(k-1)步 
    			q.push(e.to); 
    		}
    	}
    }
    int lca(int x,int y){
    	if(d[y] < d[x])	swap(x,y); 
    	for(int i = deep;i >= 0;i--)//将y上升至和x同一高度 
    		if(d[f[y][i]] >= d[x])	y = f[y][i];
    	if(x == y)	return x;
    	for(int i = deep;i >= 0;i--)//将x和y同时上升2^i个高度,如果相等,说明f[x][0]为答案 
    		if(f[x][i] != f[y][i])	x = f[x][i],y = f[y][i];
    	return f[x][0];
    		
    }
    void init(int n){
    	memset(f,0,sizeof f);
    	memset(d,0,sizeof d);
    	memset(Dist,0,sizeof Dist);
    	edges.clear();
    	for(int i = 0;i <= n;i++)	G[i].clear();
    }
    int main()
    {
    	int t;
    	scanf("%d",&t);
    	while(t--){
    		int n,m;
    		scanf("%d%d",&n,&m);
    		init(n);
    		deep = (int)(log(n)/log(2))+1;
    	
    		for(int i = 0;i < n-1;i++){
    			int x,y,z;
    			scanf("%d%d%d",&x,&y,&z);
    			add_edge(x,y,z);
    			add_edge(y,x,z);
    		}
    		bfs();
    		for(int i = 0;i < m;i++){
    			int x,y;
    			scanf("%d%d",&x,&y);
    			printf("%d
    ",Dist[x]+Dist[y]- 2*Dist[lca(x,y)]);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    测试:安装测试用例
    测试:界面测试
    软件项目管理:什么是baseline
    测试:fiddler使用
    android adb常用指令
    sqlite语句主页
    几条常见的数据库分页 SQL 语句
    linux下tomcat无法访问问题(换一种说法:无法访问8080端口)
    eclipse中svn的各种状态图标详解
    Tomcat项目部署方式
  • 原文地址:https://www.cnblogs.com/long98/p/10352193.html
Copyright © 2020-2023  润新知