CCF CSP 201909-5 城市规划

 有依赖的树形背包问题

第一维 循环物品

第二维 循环体积

第三维 循环决策

#include 
#define LL long long
using namespace std;
const int N = 1e5+10, M = 5e5+10;
const int INF = 1e15;
int h[N], ep;
struct Edge{
	int to, nxt, w;
}e[M];
int n, m, K;
int du[N], vis[N], siz[N];
LL f[N][110];
void add(int a, int b,int c)
{
	e[ep].to = b, e[ep].w = c, e[ep].nxt = h[a], h[a] = ep ++;
}
void dfs(int u,int fa)
{
	for(int i = 1; i <= K; ++i) f[u][i] = INF;
	if(vis[u]) siz[u] = 1, f[u][1] = 0;
	for(int i = h[u]; ~i; i = e[i].nxt)
	{
		int to = e[i].to;
		LL w = e[i].w;
		if(to == fa) continue;
		dfs(to, u);
		siz[u] += siz[to];
		for(int j = min(siz[u], K); j; j --)
			for(int k = min(siz[to], j); k; k --)
				f[u][j] = min(f[u][j], f[u][j - k] + f[to][k] + w * (K - k) * k);
	}
}
int main()
{
	memset(h, -1, sizeof h);
	//freopen("1.txt", "r", stdin);
	scanf("%d%d%d",&n, &m, &K);
	for(int i = 1, x; i <= m; ++i) scanf("%d",&x), vis[x] = 1;
	for(int i = 1; i < n; ++i)
	{
		int a, b, c; scanf("%d%d%d",&a, &b, &c);
		add(a, b, c); add(b, a, c);
		du[b] ++;
	}
	int rt = 1;
	while(!du[rt]) rt ++;
	dfs(rt, -1);
	printf("%lld\n", f[rt][K]);
}

 

你可能感兴趣的:(CCF,背包DP,树形DP)