【题解】climb树
考虑反向建单向图,在每层建虚拟点,
Dijkstra求解单源最短路即可
#include<bits/stdc++.h>
using namespace std;
inline int Read(){
int s = 0 , w = 1;
char ch = getchar();
while(ch > '9' || ch < '0'){
if(ch == '-') w = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9'){
s = (s << 3) + (s << 1) + ch - '0';
ch = getchar();
}
return s * w;
}
#define int long long
const int MAXN = 2e6 + 50;
int head[MAXN],to[MAXN << 1],val[MAXN << 1],nxt[MAXN << 1],tot;
void add(int x,int y,int v){
to[++tot] = y;
nxt[tot] = head[x];
head[x] = tot;
val[tot] = v;
}
int n,k,maxd,dep[MAXN];
bool lc[MAXN];
void dfs(int u,int f){
dep[u] = dep[f] + 1;
maxd = max(maxd,dep[u]);
add(u,n + dep[u],0);
if(!lc[u]) add(n + dep[u],u,0);
for(int i = head[u] ; i ; i = nxt[i]){
int v = to[i];
if(v == f || v > n) continue;
dfs(v,u);
}
}
int d[MAXN];
priority_queue<pair<int,int> >Q;
bool vis[MAXN];
void Dijkstra(){
memset(d,127,sizeof(d));
memset(vis,false,sizeof(vis));
d[1] = 0;
Q.push(make_pair(0,1));
while(!Q.empty()){
int u = Q.top().second;Q.pop();
if(vis[u]) continue;
vis[u] = true;
for(int i = head[u] ; i ; i = nxt[i]){
int v = to[i];
if(d[v] > d[u] + val[i]){
d[v] = d[u] + val[i];
Q.push(make_pair(-d[v],v));
}
}
}
}
#undef int
int main(){
#define int long long
n = Read() , k = Read();
for(int i = 2 ; i <= n ; i++){
int fa = Read();
int val = Read();
lc[i] = Read();
add(fa,i,val);
}
dfs(1,0);
for(int i = 2 ; i <= maxd ; i ++){
add(n + i - 1,n + i,k);
}
Dijkstra();
for(int i = 1 ; i <= n ; i ++){
printf("%d\n",d[i]);
}
return 0;
}