Description

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

Input

第一行包含两个正整数\(N,M\)。

下面\(N − 1\)行,每行三个正整数\(a, b, c (a, b \le N, c \le 10,000)\),表示结点\(a\)和结点\(b\)间有一条权值为\(c\)的边相连。

Output

共\(M\)行,每行一个正整数,第\(i\)行表示排在第\(i\)个的距离值。

Sample Input

5 10

1 2 1

1 3 2

2 4 3

2 5 4

Sample Output

7

7

6

5

4

4

3

3

2

1

Hint

\(N \le 50000,M \le min(\frac{N(N-1)}{2},30,000)\)

点分治+K路归并。由于树上的每条路径必定经过一个重心,在进行点分治时我们可以枚举到所有的路径。将重心到每个点的距离按dfs序插入数组(可以把每次分治的结果都插入数组中,数组开\(O(NlogN)\))中。由于保证枚举的两个点不在一棵子数中,每个点对应的链在dfs数组中一定是段连续的区间,故可以采用超级钢琴的做法。代码如下:

#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<set>
#include<vector>
using namespace std; #define maxn (100010)
int N,M,next[maxn],toit[maxn],len[maxn],side[maxn],L,R,f[20][maxn*10],bit[maxn*10];
int cnt = 1,num,size[maxn],large[maxn],dis[maxn*10],best; bool vis[maxn];
struct node
{
int pos,l,r,mx,key;
friend inline bool operator <(const node &a,const node &b) { return a.key > b.key; }
};
vector <node> vec; multiset <node> S; inline void add(int a,int b,int c) { next[++cnt] = side[a]; side[a] = cnt; toit[cnt] = b; len[cnt] = c; }
inline void ins(int a,int b,int c) { add(a,b,c); add(b,a,c); } inline void getroot(int now,int fa,int rest)
{
size[now] = 1; large[now] = 0;
for (int i = side[now];i;i = next[i])
{
if (toit[i] == fa||vis[toit[i]]) continue;
getroot(toit[i],now,rest);
size[now] += size[toit[i]];
large[now] = max(large[now],size[toit[i]]);
}
large[now] = max(large[now],rest-size[now]);
if (large[now] < large[best]) best = now;
}
inline int find_root(int now,int rest) { best = 0; getroot(now,0,rest); return best; } inline void dfs(int now,int fa,int d)
{
dis[++cnt] = d; vec.push_back((node){cnt,L,R,0,0});
for (int i = side[now];i;i = next[i])
if (toit[i] != fa&&!vis[toit[i]])
dfs(toit[i],now,d+len[i]);
} inline void cut(int now)
{
vis[now] = true; L = R = ++cnt;
for (int i = side[now];i;i = next[i])
{
if (vis[toit[i]]) continue;
dfs(toit[i],now,len[i]); R = cnt;
}
for (int i = side[now];i;i = next[i])
if (!vis[toit[i]]) cut(find_root(toit[i],size[toit[i]]));
} inline int query(int l,int r)
{
int len = r-l+1,lg = bit[len];
if (dis[f[lg][l]] > dis[f[lg][r-(1<<lg)+1]]) return f[lg][l];
else return f[lg][r-(1<<lg)+1];
} int main()
{
freopen("path.in","r",stdin);
freopen("path.out","w",stdout);
scanf("%d %d",&N,&M);
for (int i = 1,a,b,c;i < N;++i) scanf("%d %d %d",&a,&b,&c),ins(a,b,c);
large[0] = 1<<30; cnt = 0; cut(find_root(1,N));
for (int i = 1;(1 << i) <= (cnt<<1);++i)
for (int j = (1<<(i-1));j <= (1<<i)-1&&j <= cnt;++j) bit[j] = i-1;
for (int i = 1;i <= cnt;++i) f[0][i] = i;
for (int i = 1;i <= bit[cnt];++i)
for (int j = 1;j+(1<<i)-1 <= cnt;++j)
{
if (dis[f[i-1][j]] > dis[f[i-1][j+(1<<(i-1))]]) f[i][j] = f[i-1][j];
else f[i][j] = f[i-1][j+(1<<(i-1))];
}
int nn = vec.size();
for (int i = 0;i < nn;++i)
{
node tmp = vec[i];
tmp.mx = query(tmp.l,tmp.r); tmp.key = dis[tmp.pos]+dis[tmp.mx];
S.insert(tmp);
}
for (int i = 1;i <= M;++i)
{
node now = *S.begin(); S.erase(S.begin());
printf("%d\n",now.key);
if (now.mx > now.l)
{
node tmp; tmp = now;
tmp.mx = query(tmp.l,tmp.mx-1);
tmp.key = dis[tmp.mx]+dis[tmp.pos];
tmp.r = now.mx-1; S.insert(tmp);
}
if (now.mx < now.r)
{
node tmp; tmp = now;
tmp.mx = query(tmp.mx+1,tmp.r);
tmp.key = dis[tmp.mx]+dis[tmp.pos];
tmp.l = now.mx+1; S.insert(tmp);
}
}
fclose(stdin); fclose(stdout);
return 0;
}

CTSC模拟题 树上的路径的更多相关文章

  1. 某模拟赛C题 树上路径统计 (点分治)

    题意 给定一棵有n个节点的无根树,树上的每个点有一个非负整数点权.定义一条路径的价值为路径上的点权和-路径上的点权最大值. 给定参数P,我!=们想知道,有多少不同的树上简单路径,满足它的价值恰好是P的 ...

  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. 全国信息学奥林匹克联赛 ( NOIP2014) 复赛 模拟题 Day1 长乐一中

    题目名称 正确答案  序列问题 长途旅行 英文名称 answer sequence travel 输入文件名 answer.in sequence.in travel.in 输出文件名 answer. ...

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

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

  6. ACdreamoj(1105)模拟题

    题意:射一次激光最多能够攻击到几个敌人(因为激光非常强大,能够在击中敌人后穿过它,而瑶瑶自己的坦克因为有特殊装置,所以不会被激光击中.激光也会直接穿过它) . 表示此处为空地 * 表示此处为障碍(激光 ...

  7. NOIP模拟题 2017.7.3 - 模拟 - 贪心 - 记忆化搜索

    直接暴力模拟,注意判数据结构为空时的取出操作. Code #include<iostream> #include<cstdio> #include<ctime> # ...

  8. NOIP模拟题汇总(加厚版)

    \(NOIP\)模拟题汇总(加厚版) T1 string 描述 有一个仅由 '0' 和 '1' 组成的字符串 \(A\),可以对其执行下列两个操作: 删除 \(A\)中的第一个字符: 若 \(A\)中 ...

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

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

随机推荐

  1. There is an error while getting planid. No Free partitions available

    问题概述 Oracle Advanced Supply Chain Planning最初的设置职责的时候有点问题,不知是不是要打什么补丁或其它配置什么东东,, 这个提示,,但我查到的分区是还有可用分区 ...

  2. [Java Performance] 数据库性能最佳实践 - JPA和读写优化

    数据库性能最佳实践 当应用须要连接数据库时.那么应用的性能就可能收到数据库性能的影响. 比方当数据库的I/O能力存在限制,或者因缺失了索引而导致运行的SQL语句须要对整张表进行遍历.对于这些问题.只相 ...

  3. oracle13 触发器 变量

    触发器   触发器是指隐含的执行的存储过程.当定义触发器时,必须要指定触发的事件和触发的操作,常用的触发事件包括insert,update,delete语句,而触发操作实际就是一个pl/sql块.可以 ...

  4. Hibernate 配置派生属性

    在持久化类中,有些属性在表中没有对应的字段,可以在映射文件中设置派生属性. 比如在一个订单中有多个商品的价格,但没有计算总的价格,可以在持久化类中增添一个统计总价格的属性,在映射文件中配置一些信息. ...

  5. plupload使用指南(转)

    转自http://www.cnblogs.com/2050/p/3913184.html 现在随着html5技术的逐渐推广和普及,再去使用以flash为上传手段的SWFUpload显然就有点过时了,毕 ...

  6. windows向ubuntu过渡之常用软件安装

    好久没有写博客了,介于最近上操作系统实验课,好多同学装上了ubuntu,网上的教程比较杂乱,下面我就总结分享一些安装完ubuntu要安装的常用软件,会持续更新... 1.搜狗拼音安装 (1)在安装输入 ...

  7. RedHat7/Windows7搭建JAVA开发环境(Eclipse)

    RedHat7搭建JAVA开发环境 安装JAVA # yum install java 安装Tomcat # yum install tomcat 确认Tomcat版本 # tomcat versio ...

  8. ASP.NET中常用方法

    身份证号检测: /// <summary> /// 检验身份证号是否正确 /// </summary> /// <param name="Id"> ...

  9. JOSN对象与JSON字符串的相互转化

    前端在与服务端通信时.会与JSON JSON字符串经常打交道. 什么是JSON?  如果不太清楚可以点击这里 服务端传过来的数据一般都是一串字符串,jQuery AJAX中的success函数的第一个 ...

  10. 用Eclipse+xdebug调试PHP总是在首行自动断点解决方法

    问题描述: 使用Eclipse+PDT+xdebug调试PHP程序时,总是在程序的第一行(首行)自动断点,不方便调试. 解决方法: 分别在下面3个位置配置,取消 Break at First Line ...