You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
2.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 500010, M = N << 1;
#define int long long
int n, m;
// 链式前向星
int e[M], h[N], idx, w[M], ne[M];
void add(int a, int b, int c = 0) {
e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
int sz[N]; // 哪个点上有人
int len[N]; // len[u]:经过u的最长链
int id[N]; // id[u]:最长链的第一节点
int slen[N]; // slen[u]:经过u的次长链
int f[N], g[N];
void dfs1(int u, int fa) {
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (v == fa) continue;
dfs1(v, u); // 由底向上,先递归,再更新统计信息
// 如果v这个节点及它的子节点上有人那么需要汇总统计信息到sz[u]上去
// 如果v上就没有人那就不用统计了
if (sz[v] == 0) continue;
// ① u->v,v->u一来一回路径翻倍 2*w[i]
// ② 所有子节点都对u有贡献所以f[u]+
// ③ 跑完v为根的子树后v子树的贡献要累加到u子树上所以f[u]+=f[v]+2*w[i]
f[u] += f[v] + 2 * w[i];
// len[v]:v点出发的最长链长度
int x = len[v] + w[i];
// 更新最长链
if (x >= len[u])
slen[u] = len[u], len[u] = x, id[u] = v;
else if (x > slen[u]) // 更新次长链
slen[u] = x;
// 记录累计人数
sz[u] += sz[v];
}
}
void dfs2(int u, int fa) {
for (int i = h[u]; ~i; i = ne[i]) {
int v = e[i];
if (v == fa) continue;
if (!sz[v])
g[v] = g[u] + 2 * w[i], len[v] = len[u] + w[i];
else if (m - sz[v]) {
g[v] = g[u];
if (id[u] != v && len[v] < len[u] + w[i])
slen[v] = len[v], len[v] = len[u] + w[i], id[v] = u;
else if (len[v] < slen[u] + w[i])
slen[v] = len[v], len[v] = slen[u] + w[i], id[v] = 1;
else if (slen[v] < len[u] + w[i] && id[u] != v)
slen[v] = len[u] + w[i];
else if (slen[v] < slen[u] + w[i])
slen[v] = slen[u] + w[i];
} else
g[v] = f[v];
dfs2(v, u);
}
}
signed main() {
// 初始化链式前向星
memset(h, -1, sizeof h);
cin >> n >> m;
for (int i = 1; i < n; i++) {
int a, b, c;
cin >> a >> b >> c;
add(a, b, c), add(b, a, c);
}
for (int i = 1; i <= m; i++) { // 有m个人
int x;
cin >> x;
sz[x] = 1; // x号点上有人
}
dfs1(1, 0);
g[1] = f[1];
dfs2(1, 0);
for (int i = 1; i <= n; i++) cout << g[i] - len[i] << endl;
}