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

P1364 医院设置(树型结构)

时间:2020-04-03 11:50:35      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:put   http   i++   math   增加   clu   input   size   ref   

传送门闷闷闷闷闷闷

~~放一个可爱的输入框。~~

考虑在O(n)的时间内求数以每个节点为医院的距离和。

\(设想一下,如果我们已知以1为根节点的距离和f[1],如何求出子节点呢?\)

当医院从1转换到1的儿子节点2

一、那么2为根的子树节点到医院的距离都减少1

二、其余节点到医院的距离都增加1

所以得出方程\(f[v]=f[u]-size[v]+(size[1]-size[v])\)

其中\(size[i]\)表示以i为根的子树节点数的权值和

#include <bits/stdc++.h>
using namespace std;
const int maxn=10009;
const int inf=1e9;
vector<int>vec[maxn];
int ans=inf,w[maxn],f[maxn],size[maxn];
void dfs(int now,int fa,int dep)//预处理now为根节点的子树的权值 
{
	size[now]=w[now];
	for(int i=0;i<vec[now].size();i++)
	{
		int v=vec[now][i];
		if(v==fa)	continue;
		dfs(v,now,dep+1);
		size[now]+=size[v];
	}
	f[1]+=w[now]*dep;
} 
void dp(int now,int fa)
{
	for(int i=0;i<vec[now].size();i++)
	{
		int v=vec[now][i];
		if(v==fa)	continue;
		f[v]=f[now]+size[1]-2*size[v];
		dp(v,now);
	}
	ans=min(ans,f[now]);
}
int main()
{
	int n,l,r;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>w[i]>>l>>r;
		if(l)	vec[i].push_back(l),vec[l].push_back(i);
		if(r)	vec[i].push_back(r),vec[r].push_back(i);
	}
	dfs(1,0,0);
	dp(1,0);
	cout<<ans;
}

P1364 医院设置(树型结构)

标签:put   http   i++   math   增加   clu   input   size   ref   

原文地址:https://www.cnblogs.com/iss-ue/p/12625331.html

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