Nuclear Power Plant ZOJ - 3840 树形dp
Posted zxyqzy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nuclear Power Plant ZOJ - 3840 树形dp相关的知识,希望对你有一定的参考价值。
There are N (1 ≤ N ≤ 105) cities on land, and there are N - 1 wires connecting the cities. Therefore, each city can transmit electricity to all other cities by these wires.
Dark_Sun made a decision to build a nuclear power plant to supply electricity for all the cities. The nuclear power plant can be built in any city, but the cost for the electricity transmission is very strange. Let the weight of wire which connects city u and city v is E(u, v) (|E(u, v)| < 109). If the power plant is built in city x, the cost for electricity transmission from city x to city y is D(x, y) = (E(x, s1) + E(s1, s2) + ... + E(sp, y))k, where {x, s1, s2, ..., sp, y} is the path from x to y. Because of the bug of the computer, the total cost for building a nuclear power plant in city x is Σ(D(x, i)) mod 100000007 (0 ≤ i < N, i ≠ x), and the total cost is obviously not a negative number.
Dark_Sun asks you to write a program to calculate the minimum total cost.
Input
Input will consist of multiple test cases.
The first line of each test case contains two integers N, K (1 ≤ N ≤ 105,0 ≤ K ≤ 10).
The next N - 1 lines, each line contains three integers u, v, w (0 ≤ u, v < N, |w| < 109, u ≠ v), indicating E(u, v) is w.
OutputFor each case, output one line with one integer, indicating the minimum total cost.
Sample Input3 2 0 1 2 1 2 2Sample Output
8
#include<iostream> #include<cstdio> #include<algorithm> #include<cstdlib> #include<cstring> #include<string> #include<cmath> #include<map> #include<set> #include<vector> #include<queue> #include<bitset> #include<ctime> #include<time.h> #include<deque> #include<stack> #include<functional> #include<sstream> //#include<cctype> //#pragma GCC optimize(2) using namespace std; #define maxn 100005 #define inf 0x7fffffff //#define INF 1e18 #define rdint(x) scanf("%d",&x) #define rdllt(x) scanf("%lld",&x) #define rdult(x) scanf("%lu",&x) #define rdlf(x) scanf("%lf",&x) #define rdstr(x) scanf("%s",x) #define mclr(x,a) memset((x),a,sizeof(x)) typedef long long ll; typedef unsigned long long ull; typedef unsigned int U; #define ms(x) memset((x),0,sizeof(x)) const long long int mod = 100000007; #define Mod 1000000000 #define sq(x) (x)*(x) #define eps 1e-5 typedef pair<int, int> pii; #define pi acos(-1.0) //const int N = 1005; #define REP(i,n) for(int i=0;i<(n);i++) typedef pair<int, int> pii; inline int rd() { int x = 0; char c = getchar(); bool f = false; while (!isdigit(c)) { if (c == ‘-‘) f = true; c = getchar(); } while (isdigit(c)) { x = (x << 1) + (x << 3) + (c ^ 48); c = getchar(); } return f ? -x : x; } ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a%b); } int sqr(int x) { return x * x; } /*ll ans; ll exgcd(ll a, ll b, ll &x, ll &y) { if (!b) { x = 1; y = 0; return a; } ans = exgcd(b, a%b, x, y); ll t = x; x = y; y = t - a / b * y; return ans; } */ int n, K; struct node { int u, v; ll w; int nxt; }e[maxn<<1]; ll dp[maxn][12]; int head[maxn]; int tot; ll C[14][14]; void init() { C[0][0] = C[1][1] = C[1][0] = 1; for (int i = 2; i <= 13; i++) { C[i][i] = C[i][0] = 1; for (int j = 1; j < i; j++) { C[i][j] = C[i - 1][j - 1] + C[i - 1][j]; C[i][j] %= mod; } } } void addedge(int u, int v, ll w) { e[++tot].u = u; e[tot].v = v; e[tot].w = w; e[tot].nxt = head[u]; head[u] = tot; } void dfs1(int u, int fa) { // ms(dp[u]); dp[u][0] = 1; for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].v; if (v == fa)continue; dfs1(v, u); for (int k = 0; k <= K; k++) { ll ut = 1; for (int j = 0; j <= k; j++) { dp[u][k] = (dp[u][k] + C[k][j] * dp[v][k - j] % mod*ut%mod) % mod; dp[u][k] = (dp[u][k] % mod + mod) % mod; ut = ut * e[i].w%mod; } } } return; } void dfs2(int u, int fa) { for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].v; if (v == fa)continue; ll tmp[20]; for (int k = 0; k <= K; k++) { tmp[k] = dp[u][k]; ll ut = 1; for (int j = 0; j <= k; j++) { tmp[k] = (tmp[k] - C[k][j] * dp[v][k - j] % mod*ut%mod) % mod; tmp[k] = (tmp[k] % mod + mod) % mod; ut = ut * e[i].w%mod; } } for (int k = 0; k <= K; k++) { ll ut = 1; for (int j = 0; j <= k; j++) { dp[v][k] = (dp[v][k] + C[k][j] * tmp[k - j] % mod*ut%mod) % mod; dp[v][k] = (dp[v][k] % mod + mod) % mod; ut = ut * e[i].w%mod; } } } for (int i = head[u]; i; i = e[i].nxt) { int v = e[i].v; if (v == fa)continue; dfs2(v, u); } } int main() { // ios::sync_with_stdio(0); init(); while (scanf("%d%d",&n,&K)!=EOF) { // ms(e); ms(head); tot = 0; ms(dp); for (int i = 1; i < n; i++) { int u, v; rdint(u); rdint(v); ll w; rdllt(w); u++; v++; addedge(u, v, w); addedge(v, u, w); } if (K == 0) { cout << n - 1 << endl; continue; } dfs1(1, -1); dfs2(1, -1); ll ans = -inf; for (int i = 1; i <= n; i++) { if (ans == -inf || ans > dp[i][K])ans = dp[i][K]; } printf("%lld ", 1ll * ans); } return 0; }
以上是关于Nuclear Power Plant ZOJ - 3840 树形dp的主要内容,如果未能解决你的问题,请参考以下文章
LA 6437 Power Plant (prim最小生成树)
Codeforces Round #248 (Div. 1) D - Nanami's Power Plant 最小割