点分治,当一个节点作为重心时,统计出:1.每一个点的深度;2.每一个点所能选择的路径对应点区间,可以发现这样的点数只需要nlogn。然后类似于bzoj2006超级钢琴的堆+线段树来做即可。

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 50005
4 #define L (k<<1)
5 #define R (L+1)
6 #define mid (l+r>>1)
7 struct ji{
8 int nex,to,len;
9 }edge[N<<1];
10 int E,r,n,m,x,y,z,tot,s[N*20],sz[N],head[N],vis[N],f[N*80];
11 struct ji2{
12 int l,r;
13 }a[N*20];
14 struct ji3{
15 int k,l,r,mx;
16 bool operator < (const ji3 &t)const{
17 return s[k]+s[mx]<s[t.k]+s[t.mx];
18 }
19 };
20 priority_queue<ji3>q;
21 int up(int x,int y){
22 if (s[x]>s[y])return x;
23 return y;
24 }
25 void update(int k,int l,int r,int x){
26 if (l==r){
27 f[k]=l;
28 return;
29 }
30 if (x<=mid)update(L,l,mid,x);
31 else update(R,mid+1,r,x);
32 f[k]=up(f[L],f[R]);
33 }
34 int query(int k,int l,int r,int x,int y){
35 if ((l>y)||(x>r))return 0;
36 if ((x<=l)&&(r<=y))return f[k];
37 return up(query(L,l,mid,x,y),query(R,mid+1,r,x,y));
38 }
39 void add(int k,int x,int y){
40 q.push(ji3{k,x,y,query(1,1,tot,x,y)});
41 }
42 void add_edge(int x,int y,int z){
43 edge[E].nex=head[x];
44 edge[E].to=y;
45 edge[E].len=z;
46 head[x]=E++;
47 }
48 void size(int k,int fa){
49 sz[k]=1;
50 for(int i=head[k];i!=-1;i=edge[i].nex)
51 if ((!vis[edge[i].to])&&(edge[i].to!=fa)){
52 size(edge[i].to,k);
53 sz[k]+=sz[edge[i].to];
54 }
55 }
56 void find(int k,int fa,int s){
57 int t=s-sz[k];
58 for(int i=head[k];i!=-1;i=edge[i].nex)
59 if ((!vis[edge[i].to])&&(edge[i].to!=fa)){
60 find(edge[i].to,k,s);
61 t=max(t,sz[edge[i].to]);
62 }
63 if (t<=s/2)r=k;
64 }
65 void calc(int k,int fa,int sh){
66 if (fa)a[++tot]=ji2{x,y};
67 else a[x=y=++tot]=ji2{0,0};
68 s[tot]=sh;
69 for(int i=head[k];i!=-1;i=edge[i].nex)
70 if ((!vis[edge[i].to])&&(edge[i].to!=fa)){
71 calc(edge[i].to,k,sh+edge[i].len);
72 if (!fa)y=tot;
73 }
74 }
75 void dfs(int k){
76 size(k,0);
77 find(k,0,sz[k]);
78 calc(k=r,0,0);
79 vis[k]=1;
80 for(int i=head[k];i!=-1;i=edge[i].nex)
81 if (!vis[edge[i].to])dfs(edge[i].to);
82 }
83 int main(){
84 scanf("%d%d",&n,&m);
85 memset(head,-1,sizeof(head));
86 for(int i=1;i<n;i++){
87 scanf("%d%d%d",&x,&y,&z);
88 add_edge(x,y,z);
89 add_edge(y,x,z);
90 }
91 dfs(1);
92 s[0]=-0x3f3f3f3f;
93 for(int i=1;i<=tot;i++)update(1,1,tot,i);
94 for(int i=1;i<=tot;i++)add(i,a[i].l,a[i].r);
95 for(int i=1;i<=m;i++){
96 ji3 o=q.top();
97 q.pop();
98 printf("%d\n",s[o.k]+s[o.mx]);
99 if (o.l<o.mx)add(o.k,o.l,o.mx-1);
100 if (o.mx<o.r)add(o.k,o.mx+1,o.r);
101 }
102 }
