zoukankan      html  css  js  c++  java
  • CF-div2-620-E. 1-Trees and Queries LCA 树上点距离

    思路

    树链剖分求出LCA
    用LCA求两点之间距离(借助到根的距离):depth[x] + depth[y] - 2*depth[LCA];
    加边后a,b两点可以保持距离为k的条件: k>=改变后的距离; 改变后的距离刚好等于k,如果不等那么距离相差偶数,来回走来走去就能走到走凑成k

    考虑加边对a,b距离的影响;有三种情况
    1.加边后,不影响a,b
    2.a先到x,x再走到y(这里新加的边,距离为1),y再走到b
    3.a先到y,y再走到x(+1),x再走到b

    判断最终距离<=k,并且相差为偶数

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn = 1e5+100;
    vector<int> g[maxn];
    ll fa[maxn],depth[maxn],sz[maxn],son[maxn],id[maxn],rk[maxn],top[maxn],bot[maxn];
    int cnt = 0;
    int n,q,root = 1;
    
    /*
    树链剖分求LCA
    LCA求两点之间距离(借助到根的距离):depth[x] + depth[y] - 2*depth[LCA];
    可以保持距离为k的条件: k>=改变后的距离; 改变后的距离刚好等于k,如果不等那么距离相差偶数,来回走来走去就能走到走凑成k
    */
    
    void dfs(int x,int deep){
    	depth[x] = deep;
    	sz[x] = 1;
    	for(int li = 0;li<g[x].size();li++){
    		int i = g[x][li];
    		if(i == fa[x]) continue;
    		fa[i] = x;
    		dfs(i,deep+1);
    		sz[x] += sz[i];
    		if(sz[i] > sz[son[x]]) son[x] = i;
    	}
    }
    
    void dfs2(int x,int tp){
    	top[x] = tp;
    	id[x] = ++cnt;
    	rk[cnt] = x;
    	if(son[x]) dfs2(son[x],tp),bot[x] = bot[son[x]];
    	else bot[x] = x;
    	for(int li=0;li<g[x].size();li++){
    		int i = g[x][li];
    		if(i != fa[x] && i != son[x])
    			dfs2(i,i);
    	}
    }
    
    int lca(int u,int v){
    	while(top[u] != top[v]){
    		if(depth[top[u]] < depth[top[v]]) swap(u,v);
    		u = fa[top[u]];
    	}
    	if(depth[u] < depth[v]) return u;
    	return v;
    }
    
    //求两点之间的简单路径距离 
    ll dis(int x,int y){
    	int LCA = lca(x,y);
    	return depth[x] + depth[y] - 2*depth[LCA];
    }
    
    int main(){
    	ios::sync_with_stdio(false);
    	cin>>n;
    	for(int i=1;i<=n-1;i++){
    		ll u,v;
    		cin>>u>>v;
    		g[u].push_back(v);
    		g[v].push_back(u);
    	}
    	dfs(root,1);
    	dfs2(root,root);
    	cin>>q;
    	while(q--){
    		ll x,y,a,b,k;
    		cin>>x>>y>>a>>b>>k;
    		ll ans = 0x3f3f3f3f;
    		//a,b两点与x,y有三种关系
    		ll dist1 = dis(a,b); //无关 
    		ll dist2 = dis(a,x) + dis(y,b) + 1; //a先到x,x再走到y(这里新加的边,距离为1),y再走到b 
    		ll dist3 = dis(a,y) + dis(x,b) + 1;
    		bool flag = false;
    		if((k - dist1)%2 == 0 && dist1 < ans) ans = dist1;
    		if((k - dist2)%2 == 0 && dist2 < ans) ans = dist2;
    		if((k - dist3)%2 == 0 && dist3 < ans) ans = dist3;
    		if(ans <= k) flag = true;
    		if(flag) puts("YES");
    		else puts("NO");
    	}
    	return 0;
    }
    /*
    5
    1 2
    2 3
    3 4
    4 5
    5
    1 3 1 2 2
    1 4 1 3 2
    1 4 1 3 3
    4 2 3 3 9
    5 2 3 3 9
    */
    
  • 相关阅读:
    springboot配置视图控制器
    springboot测试的方法
    cookie之sameSite
    docker 安装Elasticsearch +kibana
    find + xargs 删除文件名中含有空格的文件
    git,composer 代理
    Composer更新依赖报错Fatal error解决方案
    compose 设置代理 SET HTTP_PROXY="http://192.168.1.103:8080"
    php使用composer常用问题及解决办法集:zlib_decode():data error......
    ERROR: .FileNotFoundError: [Errno 2] No such file or directory: '.\docker-compose.yml:docker-compose.apache.yml'
  • 原文地址:https://www.cnblogs.com/fisherss/p/12385121.html
Copyright © 2011-2022 走看看