码迷,mamicode.com
首页 > 其他好文 > 详细

Nuclear Power Plant ZOJ - 3840 树形dp

时间:2019-02-07 22:05:50      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:mit   efi   first   case   print   sizeof   imu   技术   sub   

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, ix), 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, uv), indicating E(u, v) is w.

Output

For each case, output one line with one integer, indicating the minimum total cost.

Sample Input
3 2
0 1 2
1 2 2
Sample 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\n", 1ll * ans);
	}
	return 0;
}

 


Nuclear Power Plant ZOJ - 3840 树形dp

标签:mit   efi   first   case   print   sizeof   imu   技术   sub   

原文地址:https://www.cnblogs.com/zxyqzy/p/10355522.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!