小C上周末和他可爱的同学小A一起去X湖玩。
X湖景区一共有n个景点,这些景点由n-1条观光道连接着,从每个景点开始都可以通过观光道直接或间接地走到其他所有的景点。小C带着小A从1号景点开始游玩。游览完第一个景点后,先由小C决定下一个游览的景点,他们一起走去那个景点玩。接下来,他们轮流决定他们下一步去哪个景点玩。他们不会选择已经走过的景点,因为重复游览一个景点是无趣的。当他们无法选择下一个景点时,他们就结束旅程。
小C是好动的男孩纸,所以他希望游览的过程尽量长,也就是走过观光道的长度和最大。而小A是文静的女孩纸,她希望游览的过程尽量短。小A和小C都极度聪明,且他们的目光都足够长远,他们做出的决策都是对自己最优的。由于小C在旅游前就仔细研究了X湖景区的地图,他可以在旅行开始前就用自己惊人的数学能力推算出他和小A旅行的路径长度。
小C的梦境是美好的。在他的梦里,他和小A又进行了n-1次旅行,第i次旅行从i+1号点开始,每次也是小C先决定下一个景点,然后小A,然后小C……直到旅行结束。现在小C希望你对于所有n次旅行,求出他和小A旅行的路径长度。
第一行一个正整数n,表示景点的个数。
接下来n-1行,每行三个正整数u,v,c。表示有一条连接u和v的双向观光道,其长度为c。
输出一共N行,每行一个正整数。第i行表示从i号点开始旅行他们走过的路径长度。
travel_sample1.in
5
1 2 1
1 3 2
2 4 3
2 5 4
travel_sample1.out
4
4
7
6
7
从1号景点开始:
若小C选择走到3号景点,则小A无法选择下一个景点,旅行的路径长度为2
若小C选择走到2号景点,则小A会在4号景点和5号景点中选择更近的4号点,然后小C无法选择下一个景点,旅行结束,旅行的路径长度会是4
所以小C会选择走到2号点,最终的路径长度是4
对于20%的数据,N ≤ 15
对于60%的数据,N ≤ 3000
对于100%的数据,N ≤ 300000, c[i] ≤ 1e9
//f[x][0]表示次优值,f[x][1]表示最优值,g数组同理
#include
#include
using namespace std;
typedef long long ll;
const ll Maxn = 1000000000000000000ll;
const int N = 3e5 + 5;
ll f[N][2], g[N][2], h[N][2];
int n;
struct Edge
{
int to, cst; Edge *nxt;
}p[N << 1], *T = p, *lst[N];
inline ll Max(const ll &x, const ll &y) {return x > y ? x : y;}
inline ll Min(const ll &x, const ll &y) {return x < y ? x : y;}
inline void addEdge(const int &x, const int &y, const int &z)
{
(++T)->nxt = lst[x]; lst[x] = T; T->to = y; T->cst = z;
(++T)->nxt = lst[y]; lst[y] = T; T->to = x; T->cst = z;
}
inline void Dfs1(const int &x, const int &fa)
{
g[x][0] = g[x][1] = Maxn;
for (Edge *e = lst[x]; e; e = e->nxt)
{
int y = e->to, z = e->cst;
if (y == fa) continue;
Dfs1(y, x);
if (g[y][1] + z > f[x][1])
f[x][0] = f[x][1], f[x][1] = g[y][1] + z;
else if (g[y][1] + z > f[x][0])
f[x][0] = g[y][1] + z;
if (f[y][1] + z < g[x][1])
g[x][0] = g[x][1], g[x][1] = f[y][1] + z;
else if (f[y][1] + z < g[x][0])
g[x][0] = f[y][1] + z;
}
if (g[x][1] == Maxn) g[x][1] = 0;
}
inline void Dfs2(const int &x, const int &fa)
{
for (Edge *e = lst[x]; e; e = e->nxt)
{
int y = e->to, z = e->cst;
if (y == fa) continue;
h[y][0] = Max(h[x][1], (g[y][1] + z == f[x][1] ? f[x][0] : f[x][1])) + z;
h[y][1] = Min(h[x][0], (f[y][1] + z == g[x][1] ? g[x][0] : g[x][1])) + z;
Dfs2(y, x);
}
}
inline int get()
{
char ch; int res = 0;
while ((ch = getchar()) < '0' || ch > '9');
res = ch - '0';
while ((ch = getchar()) >= '0' && ch <= '9')
res = (res << 3) + (res << 1) + ch - '0';
return res;
}
inline void put(ll x)
{
if (x > 9) put(x / 10);
putchar(x % 10 + 48);
}
int main()
{
freopen("travel.in", "r", stdin);
freopen("travel.out", "w", stdout);
n = get(); int u, v, x;
for (int i = 1; i < n; ++i)
{
u = get(); v = get();
addEdge(u, v, get());
}
Dfs1(1, 0);
for (Edge *e = lst[x = 1]; e; e = e->nxt)
{
int y = e->to, z = e->cst;
h[y][0] = (g[y][1] + z == f[x][1] ? f[x][0] : f[x][1]) + z;
h[y][1] = (f[y][1] + z == g[x][1] ? g[x][0] : g[x][1]) + z;
//这里注意要特别处理根的子节点情况
Dfs2(y, x);
}
for (int i = 1; i <= n; ++i)
put(Max(f[i][1], h[i][1])), putchar('\n');
}