# bzoj3784: 树上的路径

#include <bits/stdc++.h>
using namespace std;
#define IL inline
#define rint register int
#define me(x) memset(x,0,sizeof(x))
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define mid ((h+t)/2)
char ss[1<<24],*A=ss,*B=ss;
char gc()
{
}
{
rint f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=c^48;
while (c=gc(),c>47&&c<58) x=(x<<3)+(x<<1)+(c^48); x*=f;
}
const int INF=1e9;
const int N=6e5+10;
const int N2=1e8;
struct re{
int a,b,c;
}a[N];
struct re1{
int a,b,c,d,e;
};
struct cmp{
bool operator() (re1 x,re1 y)
{
return(x.a<y.a);
}
};
priority_queue<re1,vector<re1>,cmp> Q;
int s[N2],t[N2],p[N2];
bool vis[N];
IL void arr(int x,int y,int z)
{
a[l].b=y;
a[l].c=z;
}
void gr(int x,int fa)
{
son[x]=1;f[x]=0;
while (u)
{
int v=a[u].b;
if (vis[v]&&v!=fa)
{
gr(v,x);
son[x]+=son[v];
f[x]=max(f[x],son[v]);
}
u=a[u].a;
}
f[x]=max(f[x],sum-son[x]);
if(f[x]<f[rt]) rt=x;
}
void gd(int x,int fa,int bg,int ed,int z)
{
while (u)
{
int v=a[u].b;
if (vis[v]&&v!=fa)
{
d[v]=d[x]+a[u].c;
p[++cnt]=d[v];
if (x==z)
{
s[cnt]=bg; t[cnt]=cnt-1;
gd(v,x,bg,cnt-1,z);
} else
{
s[cnt]=bg; t[cnt]=ed;
gd(v,x,bg,ed,z);
}
}
u=a[u].a;
}
}
int num;
void solve(int x,int y)
{
vis[x]=0; int bg=cnt+1;
d[x]=0;
gd(x,0,bg,0,x);
p[++cnt]=0; s[cnt]=bg; t[cnt]=cnt-1;
while (u)
{
int v=a[u].b;
if (vis[v])
{
rt=0; sum=son[v];
gr(v,x);
solve(rt,y+1);
}
u=a[u].a;
}
}
int bz[20][N],bz2[20][N];
IL re query(int x,int y)
{
int z=log2(y-x+1);
if (bz[z][x]>bz[z][y-(1<<z)+1])
return((re){bz2[z][x],bz[z][x]});
else return((re){bz2[z][y-(1<<z)+1],bz[z][y-(1<<z)+1]});
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
rep(i,1,n-1)
{
int x,y,z;
arr(x,y,z); arr(y,x,z);
}
memset(vis,1,sizeof(vis));
f[0]=INF;
sum=n; gr(1,0);
solve(rt,0);
rep(i,1,cnt) bz[0][i]=p[i],bz2[0][i]=i;
rep(i,1,16)
rep(j,1,cnt)
if (bz[i-1][j]>bz[i-1][j+(1<<(i-1))])
bz[i][j]=bz[i-1][j],bz2[i][j]=bz2[i-1][j];
else bz[i][j]=bz[i-1][j+(1<<(i-1))],bz2[i][j]=bz2[i-1][j+(1<<(i-1))];
rep(i,1,cnt)
{
if (s[i]<=t[i])
{
re xx=query(s[i],t[i]);
int x=xx.a,y=xx.b;
Q.push((re1){p[i]+y,i,s[i],t[i],x});
}
}
int ans;
rep(i,1,m)
{
re1 xx=Q.top(); Q.pop();
ans=xx.a;
int j=xx.b;
if (xx.c<xx.e)
{
re z=query(xx.c,xx.e-1);
int x=z.a,y=z.b;
Q.push((re1){p[j]+y,j,xx.c,xx.e-1,x});
}
if (xx.e<xx.d)
{
re z=query(xx.e+1,xx.d);
int x=z.a,y=z.b;
Q.push((re1){p[j]+y,j,xx.e+1,xx.d,x});
}
cout<<ans<<endl;
}
return 0;
}

posted @ 2018-07-12 23:35  尹吴潇  阅读(169)  评论(0编辑  收藏  举报