3 条题解
-
3
#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
#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
#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
- 上传者