Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- long long int nodeweight[11234];
- int nodelevel[11234];
- int marc[11234];
- vector<pair<int, int> > grafo[11234]; // 1: node conectado, 2: dist;
- int ancestral[11234][14];
- int pai[11234];
- void readn(int n){
- for(int i = 0; i< n-1; i++){
- int a, b, c;
- scanf("%d %d %d", &a, &b, &c);
- //printf("li %d %d %d\n", a, b, c);
- grafo[a].push_back(make_pair(b,c));
- grafo[b].push_back(make_pair(a,c));
- }
- }
- void dfs(int x){
- marc[x] = 1;
- for(int i = 0; i< grafo[x].size(); i++){
- int viz = grafo[x][i].first;
- if(marc[viz] != 1){
- int preco = grafo[x][i].second;
- nodelevel[viz] = nodelevel[x] +1;
- nodeweight[viz] = nodeweight[x] + preco;
- pai[viz] = x;
- dfs(viz);
- }
- }
- }
- int LCA(int u , int v){
- if(nodelevel[u] < nodelevel[v]){
- swap(u,v) ;
- }
- //u is the node at a greater depth/lower level
- //So we have to raise u to be at the same
- //level as v.
- int dist = nodelevel[u] - nodelevel[v] ;
- //printf("dist %d\n",dist);
- while(dist > 0){
- int raise_by = log2(dist);
- u = ancestral[u][raise_by];
- dist -= (1<<raise_by) ;
- }
- //printf("u %d\n",u);
- if(u == v){
- return u ;
- }
- //Now we keep raising the two nodes by equal amount
- //Until each node has been raised uptill its (k-1)th ancestor
- //Such that the (k)th ancestor is the lca.
- //So to get the lca we just return the parent of (k-1)th ancestor
- //of each node
- //printf ("v %d\n", v);
- for(int j = 13 ; j >= 0 ; --j){
- //Checking P[u][j] != P[v][j] because if P[u][j] == P[v][j]
- //P[u][j] would be the Lth ancestor such that (L >= k)
- //where kth ancestor is the LCA
- //But we want the (k-1)th ancestor.
- if((ancestral[u][j] != -1) && (ancestral[u][j] != ancestral[v][j])){
- u = ancestral[u][j] ;
- v = ancestral[v][j] ;
- //printf("j %d, u %d v %d\n",j, u, v);
- }
- }
- return pai[u] ; //or parent[v]
- }
- int jumpk(int u, int k){
- int dist = k ;
- while(dist > 0){
- int raise_by = log2(dist);
- u = ancestral[u][raise_by];
- dist -= (1<<raise_by) ;
- }
- return u;
- }
- int main() {
- int t;
- //printf("%f\n", log2(10000));
- scanf("%d", &t);
- for(int testcase = 0; testcase< t; testcase++){
- if(testcase >0) printf("\n");
- int n;
- scanf("%d", &n);
- for(int i = 0; i<= n; i++){
- grafo[i].clear();
- nodeweight[i] = -1;
- nodelevel[i] = -1;
- marc[i] = -1;
- pai[i] = -1;
- }
- readn(n);
- nodelevel[1] = 0;
- nodeweight[1] = 0;
- dfs(1);
- for(int i = 1; i <= n; i++ ){
- //printf("nodelevel[%d] = %d, nodeweight = %d\n", i, nodelevel[i],nodeweight[i]);
- }
- for(int i = 1 ; i <= n ; i++){
- for(int j = 0 ; j < 14 ; j++){
- ancestral[i][j] = -1;
- }
- }
- //The first ancestor(2^0 th ancestor)
- //for every node is parent[node]
- for(int i = 1 ; i <= n ; i++){
- ancestral[i][0] = pai[i] ;
- // printf("pai[%d] = %d\n", i, pai[i]);
- }
- for(int j = 1; (1<<j) < n ; j++){
- for(int i = 1 ; i <= n ; i++){
- //If a node does not have a (2^(j-1))th ancestor
- //Then it does not have a (2^j)th ancestor
- //and hence P[i][j] should remain -1
- //Else the (2^j)th ancestor of node i
- //is the (2^(j-1))th ancestor of ((2^(j-1))th ancestor of node i)
- if(ancestral[i][j-1] != -1){
- ancestral[i][j] = ancestral[ancestral[i][j-1]][j-1] ;
- //printf("ancestral[%d][%d] = %d\n",i, j, ancestral[i][j] );
- }
- }
- }
- char coiso[5];
- scanf( " %s", coiso);
- while(coiso[1] != 'O'){
- int a, b;
- scanf("%d %d", &a, &b);
- int lca = LCA(a,b);
- //printf("lca %d, %d = %d\n", a, b, lca);
- if(coiso[1] == 'I'){
- printf("%lld\n", nodeweight[a]+nodeweight[b]-2*nodeweight[lca]);
- }else if( coiso[1] == 'T'){
- int k;
- scanf("%d", &k);
- if(nodelevel[a] - nodelevel[lca] >= k){
- printf("%d\n", jumpk(a, k-1));
- }else{
- k = nodelevel[a] - nodelevel[lca]+ nodelevel[b]-nodelevel[lca] -k +1;
- //printf("%d ", k);
- printf("%d\n", jumpk(b, k));
- }
- }
- scanf(" %s",coiso);
- }
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement