3 条题解

  • 3
    @ 2026-2-9 11:28:30
    #include<bits/stdc++.h>
    using namespace std;
    const int N = 5e5 + 10;
    vector<int> G[N];
    int D/*最大能跳多远, 即为2^D步*/, dep[N]/*节点深度*/, st[N][20]/*st[x][i]:节点x往上跳2^i步*/;
    
    void dfs(int x, int xfa)/*处理每个点跳跃达到的点, 即st[x][i]*/
    {
    	dep[x] = dep[xfa] + 1;/*记录深度*/
    	st[x][0] = xfa;/*x往上跳1步就是x的父亲*/
        for (int i = 1; i <= D; i++)
            st[x][i] = st[st[x][i-1]][i-1];/*x跳2^i步, 等于x先跳2^(i-1)步, 再跳2^(i-1)步*/
    	for (int y : G[x]) if (y != xfa)
    		dfs(y, x);/*递归x的儿子*/
    }
    
    int LCA(int x, int y)/*找x与y的LCA*/
    {
    	if (dep[x] < dep[y]) swap(x, y);/*交换x和y, 令x为更低的点*/
    	for (int i = D; i >= 0; i--)
        {
            if (dep[st[x][i]] >= dep[y]) x = st[x][i];
            /*x不断向上跳跃,直到x和y在同一深度*/
            /*从最大跳跃距离(2^D步)开始跳跃, 每次距离减半,如果不会超过目标深度就进行跳跃*/
            /*x和y的距离差一定可以拆分为若干个2^i步相加*/
        }
        if (x == y) return x; /*如果x和y是同一点则直接返回答案*/
    	for (int i = D; i >= 0; i--)
            if (st[x][i] != st[y][i]) x = st[x][i], y = st[y][i]; /*携手攀升,相遇之处即为答案*/
    	return st[x][0];
    }
    
    int jump(int x, int tar)/*将x点快速跳跃到tar深度*/
    {
        for (int i = D; i >= 0; i--)
            if (dep[st[x][i]] >= tar) x = st[x][i];/*跳跃方法和LCA()中的一样*/
        return x;
    }
    
    int main()
    {
        int n, q; cin >> n >> q;
        for (int i = 1; i <= n - 1; i++)
        {
            int a, b; cin >> a >> b;
            a ++, b ++;/*题目要求0节点为根, 节点编号均加1*/
            G[a].push_back(b);
            G[b].push_back(a);
        }
    
    	D = log2(n);/*处理一次最多可以跳几步*/
    	dfs(1, 0);/*处理每个点跳跃达到的点, 即st[x][i]*/
    
        while (q--)
        {
            int s, t, i; cin >> s >> t >> i;
            s ++, t ++;
            int lca = LCA(s, t);/*最短路径即为s->lca->t */
            int k = (dep[s] - dep[lca]) + (dep[t] - dep[lca]);/*最短路径长度*/
            if (i > k)/*如果超出路径范围则输出-1*/ { cout << -1 << '\n'; continue; }
            if (i <= (dep[s] - dep[lca]))/*如果要取的点在s->lca之间, 包括lca*/
                cout << jump(s, dep[s] - i) - 1 << '\n';
            else cout << jump(t, dep[t] - (k - i)) - 1 << '\n';
        }
        return 0;
    }
    
    • 0
      @ 2026-2-10 13:54:02
      #include<bits/stdc++.h>
      using namespace std;
      typedef long long ll;
      const int mxn=5e5+10;
      int n,q;
      int dep[mxn],fa[mxn],son[mxn],sz[mxn],st[mxn][25];
      vector<int> e[mxn];
      void dfs(int x,int xfa){
      	dep[x]=dep[xfa]+1;
      	fa[x]=xfa;
      	st[x][0]=xfa;
      	for(int i=1;i<=20;i++)st[x][i]=st[st[x][i-1]][i-1];
      	son[x]=-1;
      	sz[x]=1;
      	for(int y:e[x])if(y!=xfa){
      		dfs(y,x);
      		sz[x]+=sz[y];
      		if(son[x]==-1||sz[y]>sz[son[x]])son[x]=y;
      	} 
      }
      int dfn[mxn],top[mxn],tsp;
      void dfs2(int x,int tp){
      	top[x]=tp;
      	dfn[x]=++tsp;
      	if(~son[x]){
      		dfs2(son[x],tp);
      		for(int y:e[x])if(y!=fa[x]&&y!=son[x]){
      			dfs2(y,y);
      		}
      	}
      }
      int lca(int x,int y){
      	for(;top[x]!=top[y];x=fa[top[x]])if(dep[top[x]]<dep[top[y]])x^=y^=x^=y;
      	return dep[x]<dep[y]?x:y;
      }
      int get(int x,int k){
      	int p=0;
      	while(k){
      		if(k&1){
      			x=st[x][p];
      		}
      		p++;
      		k>>=1;
      	}
      	return x;
      }
      int main(){
      	ios::sync_with_stdio(0);
      	cin.tie(0);
      	cin>>n>>q;
      	for(int i=2,x,y;i<=n;i++){
      		cin>>x>>y;x++;y++;
      		e[y].push_back(x);
      		e[x].push_back(y);
      	}
      	dfs(1,0);
      	dfs2(1,1);
      	while(q--){
      		int x,y,k;
      		cin>>x>>y>>k;x++;y++;
      		int l=lca(x,y);
      		if(dep[x]+dep[y]-2*dep[l]+1<=k)cout<<"-1\n";
      		else{
      			if(dep[x]-dep[l]+1>k)cout<<get(x,k)-1<<'\n';
      			else cout<<get(y,(dep[y]-dep[l])-(k-(dep[x]-dep[l])))-1<<'\n';
      		}
      	} 
      	return 0;
      }
      
      
      • 0
        @ 2025-12-9 18:53:14
        #include<bits/stdc++.h>
        using namespace std;
        const int N=5e5+10;
        vector<int>G[N];
        int dep[N],st[N][20],D; 
        void dfs(int x,int f)
        {
        	dep[x]=dep[f]+1;
        	st[x][0]=f;for(int i=1;i<=D;i++)st[x][i]=st[st[x][i-1]][i-1];
        	for(int y:G[x])if(y!=f)dfs(y,x);
        }
        int lca(int x,int y)
        {
        	if(dep[x]<dep[y])swap(x,y);
        	for(int i=D;i>=0;i--)if(dep[st[x][i]]>=dep[y])x=st[x][i];
        	if(x==y)return x;
        	for(int i=D;i>=0;i--)if(st[x][i]!=st[y][i])x=st[x][i],y=st[y][i];
        	return st[x][0];
        }
        int jump(int x,int len)
        {
        	for(int i=D;i>=0;i--)if((1<<i)<=len)len-=(1<<i),x=st[x][i];
        	return x;
        }
        int main()
        {
        	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
        	int n,q;cin>>n>>q;
        	for(int i=1;i<n;i++)
        	{
        		int x,y;cin>>x>>y;x++,y++;
        		G[x].push_back(y);
        		G[y].push_back(x);
        	}
        	D=log2(n);dfs(1,0);
        	while(q--)
        	{
        		int x,y,w;cin>>x>>y>>w;x++,y++,w++;
        		int l=lca(x,y);
        		int len=dep[x]+dep[y]-2*dep[l]+1;
        		if(w>len){cout<<-1<<'\n';continue;}
        		int len1=dep[x]-dep[l]+1;
        		if(w<=len1)
        			cout<<jump(x,w-1)-1<<'\n';
        		else 
        			cout<<jump(y,len-w)-1<<'\n';
        	} 
        	return 0;
        }
        
        • 1

        信息

        ID
        8197
        时间
        2000ms
        内存
        1024MiB
        难度
        5
        标签
        递交数
        30
        已通过
        13
        上传者