树上的路径

【问题描述】

给定一个N个结点的树,结点用正整数1..N编号。每条边有一个正整数权值。用d(a,b)表示从结点a到结点b路边上经过边的权值。其中要求a<b.将这n*(n-1)/2个距离从大到小排序,输出前M个距离值。

【输入格式】

第一行两个正整数N,M
下面N-1行,每行三个正整数a,b,c(a,b<=N,C<=10000)。表示结点a到结点b有一条权值为c的边。
【输出格式】
共M行,如题所述.

【样例输入】

5 10
1 2 1
1 3 2
2 4 3
2 5 4

【样例输出】

7
7
6
5
4
4
3
3
2
1
【数据范围】

N<=50000,M<=Min(300000,n*(n-1) /2 )


题解:

考虑将点分治时访问的点的顺序作为一个序列

每个位置都有其对应的区间(指向这个位置所在重心树访问的前面所有子树,那么这就代表了这个位置对应的点出发经过这个重心的所有路径)

那么原问题转化为了BZOJ 2006 超级钢琴的问题

 #include<cmath>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int inf = ;
const int logn = ;
const int logs = ;
const int maxn = 5e4 + ;
const int maxm = maxn << ;
const int maxs = maxn * logn + ;
inline void Scan(int &x)
{
char c;
bool o = false;
while(!isdigit(c = getchar())) o = (c != '-') ? o : true;
x = c - '';
while(isdigit(c = getchar())) x = x * + c - '';
if(o) x = -x;
}
int tot, nex[maxm], ver[maxm], fir[maxn], val[maxm];
inline void Ins(int x, int y, int z)
{
nex[++tot] = fir[x];
fir[x] = tot;
ver[tot] = y;
val[tot] = z;
}
int sum, root;
int size[maxn], heavy[maxn];
bool vis[maxn];
void Getroot(int u, int f)
{
heavy[u] = ;
size[u] = ;
for(int i = fir[u]; i; i = nex[i])
{
int v = ver[i];
if(v == f || vis[v]) continue;
Getroot(v, u);
size[u] += size[v];
heavy[u] = max(heavy[u], size[v]);
}
heavy[u] = max(heavy[u], sum - size[u]);
if(heavy[u] < heavy[root]) root = u;
}
struct couple
{
int l, r;
};
couple c[maxs];
int num, l, r;
int dis[maxn], len[maxs];
int big[logs][maxs];
void Getdis(int u, int f)
{
len[++num] = dis[u], big[][num] = num;
c[num] = (couple) {l, r};
for(int i = fir[u]; i; i = nex[i])
{
int v = ver[i];
if(v == f || vis[v]) continue;
dis[v] = dis[u] + val[i];
Getdis(v, u);
}
}
void Div(int u)
{
root = ;
Getroot(u, );
l = r = ++num;
len[num] = , big[][num] = num;
vis[root] = true;
for(int i = fir[root]; i; i = nex[i])
{
int v = ver[i];
if(vis[v]) continue;
dis[v] = val[i];
Getdis(v, root);
r = num;
}
for(int i = fir[root]; i; i = nex[i])
{
int v = ver[i];
if(vis[v]) continue;
sum = size[v];
Div(v);
}
}
inline int Max(int a, int b)
{
return (len[a] > len[b]) ? a : b;
}
int bin[logs], lg[maxs];
inline void Rmq()
{
int lgn = log2(num);
bin[] = ;
for(int i = ; i <= lgn; ++i) bin[i] = bin[i - ] << , lg[bin[i]] = ;
for(int i = ; i <= num; ++i) lg[i] += lg[i - ];
for(int k = ; k <= lgn; ++k)
for(int i = ; i <= num; ++i)
{
if(i + bin[k] - > num) continue;
int j = i + bin[k - ];
big[k][i] = Max(big[k - ][i], big[k - ][j]);
}
}
inline int Query(int l, int r)
{
if(l > r) return -;
int len = lg[r - l + ];
return Max(big[len][l], big[len][r - bin[len] + ]);
}
int n, m;
struct interval
{
int l, r, a, b, v;
};
inline bool operator < (interval a, interval b)
{
return a.v < b.v;
}
priority_queue <interval> q;
int main()
{
Scan(n), Scan(m);
int a, b;
for(int i = ; i < n; ++i)
{
int c;
Scan(a), Scan(b), Scan(c);
Ins(a, b, c), Ins(b, a, c);
}
sum = n;
root = ;
heavy[] = inf;
Div();
Rmq();
int x;
for(int i = ; i <= num; ++i)
{
a = c[i].l, b = c[i].r;
if(a)
{
x = Query(a, b);
q.push((interval) {a, b, i, x, len[i] + len[x]});
}
}
int u, v;
interval s;
while(m--)
{
s = q.top(), q.pop();
u = Query(s.l, s.b - );
v = Query(s.b + , s.r);
if(u > ) q.push((interval) {s.l, s.b - , s.a, u, len[u] + len[s.a]});
if(v > ) q.push((interval) {s.b + , s.r, s.a, v, len[v] + len[s.a]});
printf("%d\n", s.v);
}
}

树上的路径 BZOJ 3784的更多相关文章

  1. bzoj 3784: 树上的路径 堆维护第k大

    3784: 树上的路径 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 88  Solved: 27[Submit][Status][Discuss] ...

  2. 【BZOJ-3784】树上的路径 点分治 + ST + 堆

    3784: 树上的路径 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 462  Solved: 153[Submit][Status][Discuss ...

  3. codevs 2756树上的路径

    题意: 2756 树上的路径  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master    题目描述 Description 给出一棵树,求出最小的k,使得,且在树 ...

  4. 【BZOJ3784】树上的路径 点分治序+ST表

    [BZOJ3784]树上的路径 Description 给定一个N个结点的树,结点用正整数1..N编号.每条边有一个正整数权值.用d(a,b)表示从结点a到结点b路边上经过边的权值.其中要求a< ...

  5. Codevs 2756 树上的路径

    2756 树上的路径  时间限制: 3 s  空间限制: 128000 KB  题目等级 : 大师 Master     题目描述 Description 给出一棵树,求出最小的k,使得,且在树中存在 ...

  6. BZOJ 3784: 树上的路径

    Description 问一棵树上前 \(k\) 大路径的边权. Sol 边分治. 非常感谢数据没有菊花图. 为了写写边分治试试然后就开了这道题. 边分治非常好想,选一条重边,分成两部分,然后分别求最 ...

  7. BZOJ.3784.树上的路径(点分治 贪心 堆)

    BZOJ \(Description\) 给定一棵\(n\)个点的带权树,求树上\(\frac{n\times(n-1)}{2}\)条路径中,长度最大的\(m\)条路径的长度. \(n\leq5000 ...

  8. bzoj 3784: 树上的路径【点分治+st表+堆】

    参考:https://www.cnblogs.com/CQzhangyu/p/7071477.html 神奇的点分治序(或者叫点剖?).就是把点分治扫过的点依次放进队列里,然后发现,对于每一棵树摊到序 ...

  9. BZOJ 3784: 树上的路径 点分治+二分+set

    很容易想出二分这个思路,但是要想办法去掉一个 $log$. 没错,空间换时间. 双指针的部分错了好几次~ Code: #include <set> #include <queue&g ...

随机推荐

  1. java基础——随机数问题

    /** * 要求:随机打印50个随机(4-10长度)的字符串,要求字符串包含的范围是所有的英文字母包含大小写和数字, * 按照编码顺序排序,每行打印4个,要求首字符对齐 * @author fanyu ...

  2. 解决升级mac os X EI Capitan后遇到LibclangError: dlopen(libclang.dylib, 6): image not found.的问题

    打开文件./frameworks/cocos2d-x/tools/bindings-generator/clang/cindex.py 把第 3395 行 改为 : library = cdll.Lo ...

  3. JavaScript中数组的使用

    ---恢复内容开始--- 创建数组 1,通过 var arr1 = [1,2,3] 2通过使用 var arr2 = new Array(1,2,3) 在这里创造的数组实际上都是一个对象,然后把对象的 ...

  4. Check for Palindromes-freecodecamp算法题目

    Check for Palindromes(检查回文字符串) 要求 给定的字符串是回文,返回true,反之,返回false.(如果一个字符串忽略标点符号.大小写和空格,正着读和反着读一模一样,那么这个 ...

  5. 【交互 细节题 思维题】cf1064E. Dwarves, Hats and Extrasensory Abilities

    第一次做交互真有趣……:挺好的细节思维题 This is an interactive problem. In good old times dwarves tried to develop extr ...

  6. java代码导出数据到Excel、js导出数据到Excel(三)

     jsp内容忽略,仅写个出发按钮:          <button style="width: 100px" onclick="expertExcel()&quo ...

  7. 运用Python制作你心目中的完美女神脸!

    简介 写这个项目的本来目的是通过构建一个神经网络来训练人脸图片,最后达到能根据图片自动判断美丑的效果.可能是因为数据集过小,或者自己参数一直没有调正确,无论我用人脸关键点训练还是卷积神经网络训练,最后 ...

  8. NXP低功耗蓝牙集成芯片QN9080C的时钟配置

    /*************************************************************************************************** ...

  9. Spring MVC+Mybatis 多数据源配置及发现的几个问题

    1.CustomerContextHolder 数据源管理类,负责管理当前的多个数据源,基于ThreadLocal实现,对每个线程设置不同的目标数据源 public class CustomerCon ...

  10. Linux中 find 常见用法示例

    Linux中find常见用法示例 #find path -option [ -print ] [ -exec -ok command ] {} \; #-print 将查找到的文件输出到标准输出 #- ...