Time Limit: 433MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu

Submit Status

Description

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:

  • DIST a b : ask for the distance between node a and node b
    or
  • KTH a b k : ask for the k-th node on the path from node a to node b

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)

Input

The first line of input contains an integer t, the number of test cases (t <= 25). t test cases follow.

For each test case:

  • In the first line there is an integer N (N <= 10000)
  • In the next N-1 lines, the i-th line describes the i-th edge: a line with three integers a b c denotes an edge between ab of cost c (c <= 100000)
  • The next lines contain instructions "DIST a b" or "KTH a b k"
  • The end of each test case is signified by the string "DONE".

There is one blank line between successive tests.

Output

For each "DIST" or "KTH" operation, write one integer representing its result.

Print one blank line after each test.

Example

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
/**
题意:给一个树,求u->v的距离
求u->v的第k个点
做法:专题是树链划分 但是想想LCA可以求距离 第k个点 要么是u->v的第k个点 要么是第k`个点
**/
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <cmath>
#include <queue>
#include <set>
using namespace std;
const int maxn = ;
const int DEG = ;
int main();
struct Edge
{
int to;
int nxt;
int val;
} edge[maxn * ];
int head[maxn], tot;
int mmap[maxn];
void addedge(int u, int v, int w)
{
edge[tot].to = v;
edge[tot].val = w;
edge[tot].nxt = head[u];
head[u] = tot++;
}
void init()
{
tot = ;
memset(head, -, sizeof(head));
}
int fa[maxn][DEG];
int deg[maxn];
void bfs(int root)
{
queue<int>que;
deg[root] = ;
mmap[root] = ;
fa[root][] = root;
que.push(root);
while(!que.empty())
{
int tmp = que.front();
que.pop();
for(int i = ; i < DEG; i++) {
fa[tmp][i] = fa[fa[tmp][i - ]][i - ];
}
for(int i = head[tmp]; i != -; i = edge[i].nxt)
{
int v = edge[i].to;
if(v == fa[tmp][]) {
continue;
}
deg[v] = deg[tmp] + ;
mmap[v] = mmap[tmp] + edge[i].val;
fa[v][] = tmp;
que.push(v);
}
}
}
int LCA(int u, int v)
{
if(deg[u] > deg[v]) {
swap(u, v);
}
int hu = deg[u];
int hv = deg[v];
int tu = u;
int tv = v;
for(int det = hv - hu, i = ; det; det >>= , i++)
if(det & ) {
tv = fa[tv][i];
}
if(tu == tv) {
return tu;
}
for(int i = DEG - ; i >= ; i--)
{
if(fa[tu][i] == fa[tv][i]) {
continue;
}
tu = fa[tu][i];
tv = fa[tv][i];
}
return fa[tu][];
}
bool flag[maxn];
int query(int u, int v, int k)
{
int root = LCA(u, v);
int ans ;
int i, j;
// cout << deg[u] << " " << deg[root] << endl;
if(deg[u] - deg[root] + >= k)
{
ans = deg[u] - k + ;
for(i = ; ( << i) <= deg[u]; i++);
i--;
for(j = i; j >= ; j--)
{
if(deg[u] - ( << j) >= ans)
{
u = fa[u][j];
}
}
return u;
}
else
{
ans = deg[root] + k - (deg[u] - deg[root] + );
cout << ans << endl;
for(i = ; ( << i) <= deg[v]; i++);
i--;
for(j = i; j >= ; j--)
{
if(deg[v] - ( << j) >= ans)
{
v = fa[v][j];
}
}
return v;
}
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n;
scanf("%d", &n);
int u, v, w;
memset(flag, false, sizeof(flag));
init();
for(int i = ; i < n - ; i++)
{
scanf("%d %d %d", &u, &v, &w);
addedge(u, v, w);
addedge(v, u, w);
flag[v] = true;
}
int root;
for(int i = ; i <= n; i++)
{
if(!flag[i])
{
root = i;
break;
}
}
bfs(root);
char ch[];
int uu, vv, ww;
while()
{
scanf("%s", ch);
if(strcmp(ch, "DONE") == ) {
break;
}
else if(strcmp(ch, "DIST") == )
{
scanf("%d %d", &uu, &vv);
// cout << deg[uu] << " " << deg[vv] << endl;
// cout << LCA(uu, vv) << ".......\n";
printf("%d\n", mmap[vv] + mmap[uu] - * mmap[LCA(uu, vv)]);
}
else
{
scanf("%d %d %d", &uu, &vv, &ww);
printf("%d\n", query(uu, vv, ww));
}
}
}
return ;
}

SPOJ-913的更多相关文章

  1. SPOJ 913 Query on a tree II

    spoj题面 Time limit 433 ms //spoj的时限都那么奇怪 Memory limit 1572864 kB //1.5个G,疯了 Code length Limit 15000 B ...

  2. QTREE2 spoj 913. Query on a tree II 经典的倍增思想

    QTREE2 经典的倍增思想 题目: 给出一棵树,求: 1.两点之间距离. 2.从节点x到节点y最短路径上第k个节点的编号. 分析: 第一问的话,随便以一个节点为根,求得其他节点到根的距离,然后对于每 ...

  3. spoj 913 Query on a tree II (倍增lca)

    Query on a tree II You are given a tree (an undirected acyclic connected graph) with N nodes, and ed ...

  4. BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5217  Solved: 1233 ...

  5. SPOJ DQUERY D-query(主席树)

    题目 Source http://www.spoj.com/problems/DQUERY/en/ Description Given a sequence of n numbers a1, a2, ...

  6. SPOJ GSS3 Can you answer these queries III[线段树]

    SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...

  7. 【填坑向】spoj COT/bzoj2588 Count on a tree

    这题是学主席树的时候就想写的,,, 但是当时没写(懒) 现在来填坑 = =日常调半天lca(考虑以后背板) 主席树还是蛮好写的,但是代码出现重复,不太好,导致调试的时候心里没底(虽然事实证明主席树部分 ...

  8. SPOJ bsubstr

    题目大意:给你一个长度为n的字符串,求出所有不同长度的字符串出现的最大次数. n<=250000 如:abaaa 输出: 4 2 1 1 1 spoj上的时限卡的太严,必须使用O(N)的算法那才 ...

  9. 【SPOJ 7258】Lexicographical Substring Search

    http://www.spoj.com/problems/SUBLEX/ 好难啊. 建出后缀自动机,然后在后缀自动机的每个状态上记录通过这个状态能走到的不同子串的数量.该状态能走到的所有状态的f值的和 ...

  10. 【SPOJ 1812】Longest Common Substring II

    http://www.spoj.com/problems/LCS2/ 这道题想了好久. 做法是对第一个串建后缀自动机,然后用后面的串去匹配它,并在走过的状态上记录走到这个状态时的最长距离.每匹配完一个 ...

随机推荐

  1. 【EasyNetQ】- 控制队列名称

    在为队列生成名称时,EasyNetQ的默认行为是使用消息类型名称并将其附加到订阅ID.例如PartyInvitation,命名空间中的消息类型EasyNetQ.Tests.Integration将使用 ...

  2. QueryHelper插件类(hql)

    package cn.itcast.core.util; import java.util.ArrayList; import java.util.List; public class QueryHe ...

  3. kali linux下的常用bash命令

    虚拟机版本默认用户root 密码toor ls:显示当前目录包含的文件及文件夹 ls -l:以常规格式显示当前目录包含的文件及文件夹(开头字母解释:d:目录 -:文件 c:设备文件 l:链接 b:块设 ...

  4. Antlr 在 idea 中正确使用的方式

    问题 Caused by: java.io.InvalidClassException: org.antlr.v4.runtime.atn.ATN; Could not deserialize ATN ...

  5. [bzoj4860] [BeiJing2017]树的难题

    Description 给你一棵 n 个点的无根树.树上的每条边具有颜色. 一共有 m 种颜色,编号为 1 到 m.第 i 种颜色的权值为 ci.对于一条树上的简单路径,路径上经过的所有边按顺序组成一 ...

  6. [bzoj2901]矩阵求和

    题目大意:给出两个$n\times n$的矩阵,$m$次询问它们的积中给定子矩阵的数值和. 题解:令为$P\times Q=R$ $$\begin{align*}&\sum\limits_{i ...

  7. 洛谷 P3477 [POI2008]PER-Permutation 解题报告

    P3477 [POI2008]PER-Permutation 题目描述 Multiset is a mathematical object similar to a set, but each mem ...

  8. bzoj2724: [Violet 6]蒲公英 分块 区间众数 论algorithm与vector的正确打开方式

    这个,要处理各个数的话得先离散,我用的桶. 我们先把每个块里的和每个块区间的众数找出来,那么在查询的时候,可能成为[l,r]区间的众数的数只有中间区间的众数和两边的数. 证明:若不是这里的数连区间的众 ...

  9. 在JS中,一切东东其实都是对象

    对象是组成JavaScript的基本单元,在JS中,一切东东其实都是对象,而且功能非常强大,它不仅风格独特,功能也与众不同. 一.引用(reference) 引用的概念是JS的基础之一,它是指向对象实 ...

  10. pmap用法小计

    By francis_hao    Aug 4,2017   pmap-报告进程的内存映射.   概要 pmap [options] pid [...]   描述 pmap命令用来报告一个或多个进程的 ...