标签:orm return can spoj assigned 位置 ati path success
You are given a tree (an undirected acyclic connected graph) with N nodes, and edges numbered 1, 2, 3...N-1. Each edge has an integer value assigned to it, representing its length.
We will ask you to perfrom some instructions of the following form:
Example:
N = 6
1 2 1 // edge connects node 1 and node 2 has cost 1
2 4 1
2 5 2
1 3 1
3 6 2
Path from node 4 to node 6 is 4 -> 2 -> 1 -> 3 -> 6
DIST 4 6 : answer is 5 (1 + 1 + 1 + 2 = 5)
KTH 4 6 4 : answer is 3 (the 4-th node on the path from node 4 to node 6 is 3)
The first line of input contains an integer t, the number of test cases (t <= 25). ttest cases follow.
For each test case:
There is one blank line between successive tests.
For each "DIST" or "KTH" operation, write one integer representing its result.
Print one blank line after each test.
Input: 1 6 1 2 1 2 4 1 2 5 2 1 3 1 3 6 2 DIST 4 6 KTH 4 6 4 DONE Output: 5 3
思路:
倍增裸题。。。套板子,
求第k个的时候需要处理下,其他没什么。,。
实现代码:
#include<bits/stdc++.h> using namespace std; #define ll long long const int M = 2e5+10; int dist[M],p[M][30],dep[M],head[M]; int cnt1,n; struct node{ int to,next,w; }e[M]; void add(int u,int v,int w){ e[++cnt1].w=w;e[cnt1].to=v;e[cnt1].next=head[u];head[u]=cnt1; e[++cnt1].w=w;e[cnt1].to=u;e[cnt1].next=head[v];head[v]=cnt1; } void dfs(int u){ for(int i = head[u];i != -1;i=e[i].next){ int v = e[i].to; if(v == p[u][0]) continue; dep[v] = dep[u] + 1; dist[v] = dist[u] + e[i].w; p[v][0] = u; //p[i][0]存i的父节点 dfs(v); } } void init(){ for(int j = 1;(1<<j)<=n;j++){ for(int i = 1;i <= n;i++){ p[i][j] = p[p[i][j-1]][j-1]; //cout<<i<<" "<<j<<" "<< p[i][j]<<endl; } } } int lca(int a,int b){ if(dep[a] > dep[b]) swap(a,b); int h = dep[b] - dep[a]; //h为高度差 for(int i = 0;(1<<i)<=h;i++){ //(1<<i)&f找到h化为2进制后1的位置,移动到相应的位置 if((1<<i)&h) b = p[b][i]; //比如h = 5(101),先移动2^0祖先,然后再移动2^2祖先 } //cout<<a<<" "<<b<<endl; if(a!=b){ for(int i = 22;i >= 0;i --){ if(p[a][i]!=p[b][i]){ //从最大祖先开始,判断a,b祖先,是否相同 a = p[a][i]; b = p[b][i]; //如不相同,a,b,同时向上移动2^j } } a = p[a][0]; //这时a的father就是LCA } return a; } int kth(int u,int k){ for(int i = 0;i < 22;i ++) if(k >> i&1) u = p[u][i]; return u; } int main() { int t,u,v,w,k; scanf("%d",&t); while(t--){ scanf("%d",&n); cnt1 = 0; //init(); memset(head,-1,sizeof(head)); for(int i = 0;i < n-1;i ++){ scanf("%d%d%d",&u,&v,&w); add(u,v,w); } dfs(1); init(); char s[10]; while(scanf("%s",s)!=EOF){ if(s[1]==‘O‘) break; scanf("%d%d",&u,&v); int num = lca(u,v); if(s[1]==‘I‘){ printf("%d\n",dist[u]+dist[v]-2*dist[num]); } if(s[1]==‘T‘){ scanf("%d",&k); int x = dep[u] - dep[num]; if(x + 1 >= k) printf("%d\n",kth(u,k-1)); else printf("%d\n",kth(v,dep[v]+dep[u]-2*dep[num]+1-k)); } } } return 0; }
标签:orm return can spoj assigned 位置 ati path success
原文地址:https://www.cnblogs.com/kls123/p/8934167.html