RT,真的是服了
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
inline int read()
{
int x=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
return x*w;
}
const int N=100005;
const int INF=0x3f3f3f3f;
const int T=20;
int n,m;
int f[N][25],depth[N];
struct Allan{
int to,nxt;
}edge[N<<1];
int edge_tot=0;
int head[N];
inline void edge_add(int from,int to)
{
edge_tot++;
edge[edge_tot].to=to;
edge[edge_tot].nxt=head[from];
head[from]=edge_tot;
return;
}
queue<int> q;
void LCA_BFS()
{
q.push(1),depth[1]=1;
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=head[x];i;i=edge[i].nxt)
{
int y=edge[i].to;
if(depth[y]) continue;
depth[y]=depth[x]+1;
f[y][0]=x;
for(int j=1;j<=T;j++)
f[y][j]=f[f[y][j-1]][j-1];
q.push(y);
}
}
return;
}
int LCA(int x,int y)
{
if(depth[x]>depth[y]) swap(x,y);
for(int i=T;i>=0;i--)
if(depth[f[y][i]]>=depth[x]) y=f[y][i];
if(x==y) return x;
for(int i=T;i>=0;i--)
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
return f[x][0];
}
struct SegmetTree{
int ls,rs;
int dat,plc;
}tree[N<<6];
int tree_tot=0;
int root[N];
inline int build()
{
tree_tot++;
tree[tree_tot].ls=tree[tree_tot].rs=tree[tree_tot].dat=0;
return tree_tot;
}
inline void update(int p)
{
if(tree[tree[p].ls].dat>=tree[tree[p].rs].dat)
{
tree[p].dat=tree[tree[p].ls].dat;
tree[p].plc=tree[p].ls;
}
else if(tree[tree[p].rs].dat>=0)
{
tree[p].dat=tree[tree[p].rs].dat;
tree[p].plc=tree[p].rs;
}
return;
}
void tree_add(int p,int l,int r,int x,int y)
{
if(l==r)
{
tree[p].dat+=y;
tree[p].plc=x;
return;
}
int mid=(l+r)>>1;
if(x<=mid)
{
if(!tree[p].ls) tree[p].ls=build();
tree_add(tree[p].ls,l,mid,x,y);
}
else
{
if(!tree[p].rs) tree[p].rs=build();
tree_add(tree[p].rs,mid+1,r,x,y);
}
update(p);
return;
}
int tree_merge(int p,int q,int l,int r)
{
if(!p) return q;
if(!q) return p;
if(l==r){tree[p].dat+=tree[q].dat;return p;}
int mid=(l+r)>>1;
tree[p].ls=tree_merge(tree[p].ls,tree[q].ls,l,mid);
tree[p].rs=tree_merge(tree[p].rs,tree[q].rs,mid+1,r);
update(p);
return p;
}
int maxz=0;
int ans[N];
void solve(int x)
{
for(int i=head[x];i;i=edge[i].nxt)
{
int y=edge[i].to;
if(y==f[x][0]) continue;
solve(y);
x=tree_merge(x,y,1,maxz);
}
ans[x]=tree[x].plc;
if(tree[x].dat==0) ans[x]=0;
return;
}
int xxx[N],yyy[N],zzz[N];
int main()
{
n=read(),m=read();
for(int i=1;i<=n-1;i++)
{
int a=read(),b=read();
edge_add(a,b),edge_add(b,a);
}
LCA_BFS();
tree_tot=n;
for(int i=1;i<=m;i++)
{
xxx[i]=read(),yyy[i]=read(),zzz[i]=read();
maxz=max(maxz,zzz[i]);
}
for(int i=1;i<=m;i++)
{
int t=LCA(xxx[i],yyy[i]);
tree_add(xxx[i],1,maxz,zzz[i],1);
tree_add(yyy[i],1,maxz,zzz[i],1);
tree_add(t,1,maxz,zzz[i],-1);
tree_add(f[t][0],1,maxz,zzz[i],-1);
}
solve(1);
for(int i=1;i<=n;i++)
printf("%d\n",ans[i]);
return 0;
}