2018-2019 ACM-ICPC, China Multi-Provincial Collegiate G. Factories(树形dp+算贡献)

Posted issue是fw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018-2019 ACM-ICPC, China Multi-Provincial Collegiate G. Factories(树形dp+算贡献)相关的知识,希望对你有一定的参考价值。

LINK

题意

给定一颗 n n n个节点的边权树,在 k k k个叶子节点建立工厂

令两两工厂的距离和最小,求出最小距离和


定义 f [ i ] [ j ] f[i][j] f[i][j]表示 i i i的子树内选择 j j j个叶子节点的距离和

转移为 f [ u ] [ i ] = min ⁡ { f [ s o n ] [ j ] + f [ u ] [ i − j ] + g [ u ] [ i − j ] ∗ g [ v ] [ j ] } f[u][i]=\\min\\{f[son][j]+f[u][i-j]+g[u][i-j]*g[v][j]\\} f[u][i]=min{f[son][j]+f[u][ij]+g[u][ij]g[v][j]}

其中 g [ u ] [ i ] g[u][i] g[u][i]表示在 u u u的子树内选 j j j个叶子节点到点 u u u的距离和

但是发现 f [ u ] [ i ] f[u][i] f[u][i] g [ u ] [ i ] g[u][i] g[u][i]并不成正比,若 f f f值小但 g g g比较大呢??

在之后的转移是不占优势的,也就是具有后效性,无法转移

考虑对每条边计算贡献,这样就不需要 g g g数组

定义 f [ i ] [ j ] f[i][j] f[i][j]表示 i i i的子树内选择 j j j个叶子节点对全局造成的最小贡献

转移为 f [ u ] [ i ] = min ⁡ { f [ s o n ] [ j ] + f [ u ] [ i − j ] + j ∗ ( k − j ) ∗ w } f[u][i]=\\min\\{f[son][j]+f[u][i-j]+j*(k-j)*w\\} f[u][i]=min{f[son][j]+f[u][ij]+j(kj)w}

其中 w w w ( u , v ) (u,v) (u,v)边的权值

这样没有后效性,类似树形背包那样转移就好了

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e6+11;
const int inf = 1e18;
int t,n,k,casenum,siz[maxn],f[100009][109];
typedef pair<int,int>p;
vector<p>vec[maxn]; 
//f[i][j]表示i的子树内选了j个工厂 
//那么需要知道j个工厂到节点i的距离和 
void dfs(int u,int fa)
{
	for(int i=1;i<=k;i++)	f[u][i] = inf;
	if( vec[u].size()==1 )	f[u][1] = 0,siz[u] = 1;
	else	siz[u] = 0;
	for( auto x:vec[u] )
	{
		int v = x.first;
		if( v==fa )	continue;
		dfs(v,u);
		for(int i=min(k,siz[u]);i>=0;i--)
		for(int j=min(k-i,siz[v]);j>=0;j--)
			f[u][i+j] = min( f[u][i+j],f[v][j]+f[u][i]+(k-j)*j*x.second );
		siz[u] += siz[v];
	}
}
signed main()
{
	cin >> t;
	while( t-- )
	{
		cin >> n >> k;
		for(int i=1;i<n;i++)
		{
			int l,r,w; scanf("%lld%lld%lld",&l,&r,&w);
			vec[l].push_back( {r,w} ), vec[r].push_back( {l,w} );
		}
		dfs(1,0);
		cout << "Case #" << ++casenum << ": ";
		cout << f[1][k] << endl;
		for(int i=1;i<=n;i++)	vec[i].clear();
	}
}

以上是关于2018-2019 ACM-ICPC, China Multi-Provincial Collegiate G. Factories(树形dp+算贡献)的主要内容,如果未能解决你的问题,请参考以下文章

2018-2019 ACM-ICPC, China Multi-Provincial Collegiate G. Factories(树形dp+算贡献)

2018-2019 ACM-ICPC, China Multi-Provincial Collegiate D. Take Your Seat(数学概率)

2016-2017 ACM-ICPC CHINA-Final

2016-2017 ACM-ICPC CHINA-Final Solution

2016-2017 ACM-ICPC CHINA-Final 个人题解

The 2018 ACM-ICPC China JiangSu Provincial Programming Contest(第六场)