JZOJ 4279. 【NOIP2015模擬10.29B組】樹上路徑
阿新 • • 發佈:2020-08-03
題目
現在有一棵n個點的無向樹,每個點的編號在1-n之間,求出每個點所在的最長路。
思路
換根 \(dp\),這裡只是記下怎麼打
#include<cstdio> #include<iostream> using namespace std; const int N = 1e5; int n , h[N + 5] , tot , f1[N + 5] , f2[N + 5] , g1[N + 5] , g2[N + 5]; struct edge{ int nxt , to , w; }e[2 * N + 5]; inline void add(int u , int v , int w) { e[++tot].to = v; e[tot].w = w; e[tot].nxt = h[u]; h[u] = tot; } inline void dfs1(int u , int fa) { for(register int i = h[u]; i; i = e[i].nxt) { int v = e[i].to; if (v == fa) continue; dfs1(v , u); if (f1[v] + e[i].w > f1[u]) f2[u] = f1[u] , f1[u] = f1[v] + e[i].w; else if (f1[v] + e[i].w > f2[u]) f2[u] = f1[v] + e[i].w; } } inline void dfs2(int u , int fa) { for(register int i = h[u]; i; i = e[i].nxt) { int v = e[i].to; if (v == fa) continue; if (f1[v] + e[i].w == g1[u]) { if (g2[u] + e[i].w > f1[v]) g1[v] = g2[u] + e[i].w , g2[v] = f1[v]; else g2[v] = g2[u] + e[i].w , g1[v] = f1[v]; } else { if (g1[u] + e[i].w > f1[v]) g1[v] = g1[u] + e[i].w , g2[v] = f1[v]; else g2[v] = g1[u] + e[i].w , g1[v] = f1[v]; } g1[v] = max(g1[v] , f1[v]) , g2[v] = max(g2[v] , f2[v]); dfs2(v , u); } } int main() { freopen("tree.in" , "r" , stdin); freopen("tree.out" , "w" , stdout); scanf("%d" , &n); int u , v , w; for(register int i = 1; i < n; i++) { scanf("%d%d%d" , &u , &v , &w); add(u , v , w) , add(v , u , w); } dfs1(1 , 0); g1[1] = f1[1] , g2[1] = f2[1]; dfs2(1 , 0); for(register int i = 1; i <= n; i++) printf("%d\n" , g1[i] + g2[i]); }