因为是涂色问题,可以采用标记l 处+1和r+1处-1,把树状结构通过树链剖分转换成线性,利用线段树维护颜色中出现的最多的,利用二分查询能够找到出现次数最多且序号最小的颜色
#include
#include
#include
#include
#define MAX 200007
using namespace std;
int n,m,z;
struct Edge
{
int v,next,c;
}e[MAX<<2];
int head[MAX];
int cc;
void add ( int u , int v , int c = 0 )
{
e[cc].v = v;
e[cc].c = c;
e[cc].next = head[u];
head[u] = cc++;
}
int dep[MAX],siz[MAX],fa[MAX],tid[MAX],son[MAX],top[MAX],rank[MAX],tim;
void init ( )
{
tim = 0;
memset ( son , -1 , sizeof ( son ) );
}
void dfs1 ( int u = 1 , int p = 0 , int d = 0 )
{
dep[u] = d , fa[u] = p , siz[u] = 1;
for ( int i = head[u] ; ~i ; i = e[i].next )
{
int v = e[i].v;
if ( v == p ) continue;
dfs1 ( v , u , d+1 );
siz[u] += siz[v];
if ( son[u]==-1 || siz[v] > siz[son[u]] ) son[u] = v;
}
}
void dfs2 ( int u = 1, int tp = 1 )
{
top[u] = tp ; tid[u] = ++tim;
rank[tid[u]] = u;
if ( son[u] == -1 ) return;
dfs2 ( son[u] , tp );
for ( int i = head[u] ; ~i ; i = e[i].next )
{
int v = e[i].v;
if ( v == fa[u] || v == son[u] ) continue;
dfs2 ( v , v );
}
}
struct Tree
{
int l,r,mx;
}tree[MAX<<2];
void build ( int u , int l , int r )
{
tree[u].l = l , tree[u].r = r;
tree[u].mx = 0;
if ( l == r ) return;
int mid = l + r >> 1;
build ( u<<1 , l , mid );
build ( u<<1|1 , mid+1 , r );
}
void push_up ( int u )
{
tree[u].mx = max ( tree[u<<1].mx , tree[u<<1|1].mx );
}
void update ( int u , int x , int v )
{
int l = tree[u].l , r = tree[u].r;
if ( l == r )
{
tree[u].mx += v;
return;
}
int mid = l + r >> 1;
if ( x > mid ) update ( u<<1|1 , x , v );
else update ( u<<1 , x , v );
push_up ( u );
}
int query ( int u )
{
int l = tree[u].l , r = tree[u].r;
if ( l == r )
return tree[u].l;
if ( tree[u].mx == tree[u<<1].mx )
return query ( u<<1 );
else return query ( u<<1|1 );
}
void find ( int x , int y , int c )
{
while ( top[x] != top[y] )
{
if ( dep[top[x]] < dep[top[y]] ) swap ( x , y );
add ( tid[top[x]] , 1 , c );
add ( tid[x]+1 , -1 , c );
x = fa[top[x]];
}
if ( dep[x] > dep[y] ) swap ( x , y );
add ( tid[x] , 1 , c );
add ( tid[y]+1 , -1 , c );
}
int ans[MAX];
int main ( )
{
while ( ~scanf ( "%d%d" , &n , &m ) , n+m )
{
int l,r,c;
memset ( head , -1 , sizeof ( head ) );
cc = 0;
for ( int i = 1 ; i < n ; i++ )
{
scanf ( "%d%d" , &l , &r );
add ( l , r );
add ( r , l );
}
init ( );
dfs1 ( );
dfs2 ( );
memset ( head , -1 , sizeof ( head ) );
cc = 0;
for ( int i = 0 ; i < m ; i++ )
{
scanf ( "%d%d%d" , &l , &r , &c );
find ( l , r , c );
}
build ( 1 , 0 , 100001 );
for ( int u = 1 ; u <= n ; u++ )
{
for ( int i = head[u] ; ~i ; i = e[i].next )
update ( 1 , e[i].c , e[i].v );
ans[rank[u]] = query ( 1 );
}
for ( int i = 1 ; i <= n ; i++ )
printf ( "%d\n" , ans[i] );
}
}