CCF 2019 September Urban Planning (contribution side of the tree dp)

Here Insert Picture Description

Ideas:
the distance between the point and the conversion to edge contributions.
And this problem exactly the same.
2018 Yinchuan tournament G - Factories Gym - 102222G (tree DP)

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;
const ll INF = 1e18;
const int maxn = 1e5 + 7;
int head[maxn << 1],nex[maxn << 1],to[maxn << 1],val[maxn << 1],tot;
int deg[maxn],siz[maxn],vis[maxn];
ll f[maxn][105];
int n,k;

void add(int x,int y,int z)
{
	to[++tot] = y;
	nex[tot] = head[x];
	val[tot] = z;
	head[x] = tot;
}

void init1()
{
	tot=0;
	for(int i = 1;i <= n;i++)
	{
		deg[i] = siz[i] = head[i] = vis[i] = 0;
	}
	for(int i = 1;i <= n;i++)
	{
		head[i + n] = 0;
	}
}
void init2()
{
	for(int i = 1;i <= n;i++)
	{
		f[i][0] = 0;
		for(int j = 1;j <= k;j++)f[i][j] = INF;
		if(vis[i] == 1)
		{
			f[i][1] = 0;
			siz[i] = 1;
		}
	}
}

void DP(int u,int fa)
{
	for(int i = head[u];i;i = nex[i])
	{
		int v = to[i],w = val[i];
		if(v == fa)continue;
		DP(v,u);
		siz[u] += siz[v];
		
		for(int i = min(k,siz[u]);i >= 1;i--)
		{
			for(int j = 1;j <= min(i,siz[v]);j++)
			{
				f[u][i] = min(f[u][i],f[u][i - j] + f[v][j] + w * (k - j) * j);
			}
		}
	}
}


int main()
{
	int kase = 0;
	int m;
	scanf("%d%d%d",&n,&m,&k);
	init1();
	for(int i = 1;i <= m;i++)
	{
		int x;scanf("%d",&x);
		vis[x] = 1;
	}
	for(int i = 1;i < n;i++)
	{
		int x,y,z;scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);add(y,x,z);
		deg[x]++;deg[y]++;
	}
	
	int rt = 1;
	init2();
	DP(rt,0);
	printf("%lld\n",f[rt][k]);
	
	return 0;
}

Published 676 original articles · won praise 18 · views 30000 +

Guess you like

Origin blog.csdn.net/tomjobs/article/details/104194032