HDU 5148 Cities
Question:
The Tree of n (2000) points selects the k (50) points from the tree and requires the selected point. The medium probability selects two points so that the expected values of these two points are least output and the expected values are multiplied by k ^ 2.
Ideas:
Sum (dis (I, j)/k ^ 2 * k ^ 2 is actually the sum (dis (I, j) where I and j are randomly selected k points
If dp [I] [k] is set, the minimum sum of k points is selected from the subtree with I as the root.
The transfer equation is dp [father] [k1 + k2] = min (dp [father] [k1] + dp [son] [k2] + edge * k2 * (k-k2) * 2) This equation is a good understanding of k2 in the attention formula. We use it for calculation because k2 points are selected in the son tree.
When writing code, you should also note that k1 needs to be dumped for this during the dp process. The 01 backpack should be well understood.
Code:
#include
#include
#include
#include
#include#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long LL;#define N 2010#define M 60inline void scand(int &ret) { char c; ret = 0; while ((c = getchar()) < '0' || c > '9') ; while (c >= '0' && c <= '9') ret = ret * 10 + (c - '0'), c = getchar();}int t, n, m;LL dp[N][M];LL ans;int head[N], tot;struct edge { int v, w, next;} ed[N * 2];void add(int u, int v, int w) { ed[tot].v = v; ed[tot].w = w; ed[tot].next = head[u]; head[u] = tot++;}void update(LL &x, LL y) { if (y == -1) return; if (x == -1 || x > y) x = y;}void dfs(int u, int fa) { dp[u][1] = 0; for (int i = head[u]; ~i; i = ed[i].next) { int v = ed[i].v; if (v != fa) { dfs(v, u); LL w = ed[i].w; for (int k1 = m - 1; k1; k1--) { if (dp[u][k1] == -1) continue; for (int k2 = 1; k2 < m; k2++) { if (k2 + k1 > m || dp[v][k2] == -1) break; update(dp[u][k1 + k2], dp[u][k1] + dp[v][k2] + w * (m - k2) * k2 * 2); } } } } update(ans, dp[u][m]);}int main() { scand(t); while (t--) { scand(n); scand(m); memset(head, -1, sizeof (head)); tot = 0; for (int i = 2; i <= n; i++) { int u, v, w; scand(u); scand(v); scand(w); add(u, v, w); add(v, u, w); } memset(dp, -1, sizeof (dp)); ans = -1; dfs(1, 0); printf("%I64d\n", ans); } return 0;}