SPOJ-913
Time Limit: 433MS | Memory Limit: 1572864KB | 64bit IO Format: %lld & %llu |
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 a, b 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的更多相关文章
- 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 ...
- QTREE2 spoj 913. Query on a tree II 经典的倍增思想
QTREE2 经典的倍增思想 题目: 给出一棵树,求: 1.两点之间距离. 2.从节点x到节点y最短路径上第k个节点的编号. 分析: 第一问的话,随便以一个节点为根,求得其他节点到根的距离,然后对于每 ...
- 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 ...
- 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 ...
- SPOJ DQUERY D-query(主席树)
题目 Source http://www.spoj.com/problems/DQUERY/en/ Description Given a sequence of n numbers a1, a2, ...
- 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 ...
- 【填坑向】spoj COT/bzoj2588 Count on a tree
这题是学主席树的时候就想写的,,, 但是当时没写(懒) 现在来填坑 = =日常调半天lca(考虑以后背板) 主席树还是蛮好写的,但是代码出现重复,不太好,导致调试的时候心里没底(虽然事实证明主席树部分 ...
- SPOJ bsubstr
题目大意:给你一个长度为n的字符串,求出所有不同长度的字符串出现的最大次数. n<=250000 如:abaaa 输出: 4 2 1 1 1 spoj上的时限卡的太严,必须使用O(N)的算法那才 ...
- 【SPOJ 7258】Lexicographical Substring Search
http://www.spoj.com/problems/SUBLEX/ 好难啊. 建出后缀自动机,然后在后缀自动机的每个状态上记录通过这个状态能走到的不同子串的数量.该状态能走到的所有状态的f值的和 ...
- 【SPOJ 1812】Longest Common Substring II
http://www.spoj.com/problems/LCS2/ 这道题想了好久. 做法是对第一个串建后缀自动机,然后用后面的串去匹配它,并在走过的状态上记录走到这个状态时的最长距离.每匹配完一个 ...
随机推荐
- tarball
环境:Linux系统 命令:tar 关键:tar打包出来的文件有没有进行压缩所得到的文件称谓不同 仅是打包,得到的文件我们称为tarfile 包含压缩,得到的文件我们称为tarball
- python字符串排序方法
一般情况下,python中对一个字符串排序相当麻烦: 一.python中的字符串类型是不允许直接改变元素的.必须先把要排序的字符串放在容器里,如list. 二.python中的list容器的sort( ...
- java线程(3)——详解Callable、Future和FutureTask
回顾: 接上篇博客 java线程--三种创建线程的方式,这篇博客主要介绍第三种方式Callable和Future.比较继承Thread类和实现Runnable接口,接口更加灵活,使用更广泛.但这两种方 ...
- IntelliJ IDEA 创建maven项目
说明 创建Maven项目的方式:手工创建 好处:参考IntelliJ IDEA 14 创建maven项目二(此文章描述了用此方式创建Maven项目的好处)及idea14使用maven创建web工程(此 ...
- delphi Edit 控制最大值,只能输入数字型 控制小数位数
delphi语言受众多程序员追捧,主要原因之一就是它有很多第三方的控件可供使用.很多资深的delphi程序员都把自己积累的函数.过程等设计成控件,以方便使用,提高开发效率. 本文通过一个只允许输入数字 ...
- Hibernate关联映射之_多对一
多对一 Employee-Department 对于 员工 和 部门 两个对象,从员工的角度来看,就是多对一的一个关系--->多个员工对应一个部门 表设计: 部门表:department,id主 ...
- 【题解】CQOI2012交换棋子
感受到网络流的强大了……这道题目的关键在于: 前后颜色不变的,流入流出的次数相等:原本是黑色的最后变成了白色,流出比流入次数多1:原本是白色最后变成黑色,流入比流出次数多一.所以我们将每一点拆成3个点 ...
- C++——内存使用
内存分配方式: (1)从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. (2)在栈上创建.在执行函数时,函数内局部变量的存储单 ...
- Android-使用ViewFlipper实现轮番切换广告栏
所谓的轮番切换广告栏,指的是下面这个东西,笔主不知道该怎么确切描述这货... 笔主没有百度研究过其他大牛是怎么实现这个功能的,在这里笔主充分发挥DIY精神,利用ViewFlipper闭门土制了一个,下 ...
- JS格式化时间(支持小程序,兼容IOS)
})-(\d{})-(\d{})T(\d{}):(\d{}):(\d{})/ /** * @function format time * @param val, format * @return {s ...