将树映射在线段上进行操作 然后每个 重链变成一个连续的区间
#include <iostream> #include <cstdio> #include <string.h> #include <vector> #include <algorithm> #pragma comment(linker,"/STACk:10240000,10240000") using namespace std; const int maxn=100005; vector<int>F[maxn]; int son[maxn],num[maxn],fa[maxn],top[maxn],p[maxn],fp[maxn],pos,depth[maxn],ans[maxn]; vector<int>P[maxn]; int loc,v; struct SegmentItree{ int num[maxn*4],id[maxn*4]; void build(int o,int L, int R){ num[o]=0; id[o]=0; if(L>=R){ num[o]=0; id[o]=L; return ; } int mid = (L+R)/2; build(o*2,L,mid ); build(o*2+1,mid+1,R); } void maintain(int o){ num[o]=0; id[o]=0; if(num[o*2]==0&&num[o*2+1]==0)return; if( num[o*2] >= num[o*2+1] ){ num[o]=num[o*2]; id[o]=id[o*2]; } else{ num[o] =num[o*2+1]; id[o]=id[o*2+1]; } } void add(int o,int L, int R){ if(L>=R){ num[o]+=v; return ; } int mid = (L+R)>>1; if(loc<=mid){ add(o*2,L,mid); }else{ add(o*2+1, mid+1,R); } maintain(o); } }T; void inti(int n){ for(int i=0; i<=n+2; ++i) F[i].clear(),P[i].clear(); pos=0; } void dfs(int cur, int per,int dep){ depth[cur]=dep; son[cur]=-1; fa[cur]=per; num[cur]=1; int Len= F[cur].size(); for(int i=0; i<Len; ++i){ int to = F[cur][i]; if(to==per) continue; dfs(to,cur,dep+1); num[cur]+=num[to]; if( son[ cur ] == -1 || num[ son[cur] ]< num[to] ) son[cur]=to; } } void finde(int cur , int per, int xx){ top[cur]=xx; pos++; p[cur]=pos; fp[pos]=cur; if(son[cur]!=-1) finde(son[cur],cur,xx); int len = F[cur].size(); for(int i=0; i<len ;++i ){ int to= F[cur][i]; if(to==per||to==son[cur])continue; finde(to,cur,to); } } void solve(int x, int y,int d){ int f1=top[x],f2=top[y]; while(f1!=f2){ if(depth[f1]<depth[f2]){ int temp = x; x=y; y= temp; temp=f1; f1=f2; f2=temp; } P[ p[f1] ].push_back(d); P[ p[x]+1 ].push_back(-d); x=fa[f1]; f1=top[x]; } if(depth[x]>depth[y]){ int temp = x; x = y ; y= temp; } P[p[x]].push_back(d); P[p[y]+1].push_back(-d); } int main() { int n,m; for(;;){ scanf("%d%d",&n,&m); if(n==0&&m==0)break; inti(n); for(int i=1; i<n ;++i ){ int a,b; scanf("%d%d",&a,&b); F[a].push_back(b); F[b].push_back(a); } dfs(1,0,0); finde(1,0,1); int N=0; for(int i=0; i<m; ++i){ int a,b,d; scanf("%d%d%d",&a,&b,&d); solve(a,b,d); N=max(d,N); } memset(ans,0,sizeof(ans)); if(N!=0){ T.build(1,1,N); for(int i=1; i<=n; ++i){ int L = P[i].size(); for(int j=0; j<L; ++j){ int to= P[i][j]; if(to>0){ v=1; loc=to; }else{ v=-1; loc=-to; } T.add(1,1,N); } if(T.num[1]!=0) ans[fp[i]]=T.id[1]; else ans[fp[i]]=0; } } for(int i=1; i<=n; ++i) printf("%d ",ans[i]); } return 0; }