P1131 [ZJOI2007]时态同步(树形DP)

it2022-05-05  117

题目

luogu1131

题解

d i s [ i ] dis[i] dis[i]表示在以 i i i为根的子树中,叶子节点到 i i i的最大距离统计时令 u u u为父亲节点, v v v为叶子节点,答案 a n s + = d i s [ u ] − ( d i s [ v ] + d i s ( u , v ) ) ans+=dis[u]-(dis[v]+dis(u,v)) ans+=dis[u](dis[v]+dis(u,v))

code

#include <map> #include <set> #include <list> #include <cmath> #include <deque> #include <stack> #include <queue> #include <cstdio> #include <cctype> #include <vector> #include <string> #include <cstring> #include <iomanip> #include <complex> #include <iostream> #include <algorithm> #include <functional> using namespace std; typedef long long LL; const int maxn = 500000 + 100; const int inf = 0x3f3f3f3f; template <class T> inline void read(T &s) { s = 0; T w = 1, ch = getchar(); while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar(); } while (isdigit(ch)) { s = (s << 1) + (s << 3) + (ch ^ 48); ch = getchar(); } s *= w; } LL ans; LL dis[maxn]; int n, s, tot; int lin[maxn]; struct Edge { int next, to, dis; } e[maxn * 2]; inline void add(int from, int to, int dis) { e[++tot].to = to; e[tot].dis = dis; e[tot].next = lin[from]; lin[from] = tot; } void dfs(int u, int fa) { for (int i = lin[u]; i; i = e[i].next) { int v = e[i].to; if (v == fa) continue; dfs(v, u); dis[u] = max(dis[u], dis[v] + e[i].dis); } for (int i = lin[u]; i; i = e[i].next) { int v = e[i].to; if (v == fa) continue; ans += dis[u] - (dis[v] + e[i].dis); } } int main() { read(n); read(s); for (int i = 1; i < n; ++i) { int u, v, w; read(u), read(v), read(w); add(u, v, w); add(v, u, w); } ans = 0ll; dfs(s, 0); printf("%lld\n", ans); return 0; }

最新回复(0)