zoukankan      html  css  js  c++  java
  • P1364 医院设置(树型结构)

    传送门闷闷闷闷闷闷

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

    考虑在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;
    }
    
  • 相关阅读:
    PHP入门03 -- 数组与数据结构
    PHP入门02 -- 函数
    PHP入门01 -- 基本语法
    node文章
    Mongodb08
    Mongodb07
    ISO处理jq事件
    map
    Django自定义模板
    JS this指向
  • 原文地址:https://www.cnblogs.com/iss-ue/p/12625331.html
Copyright © 2011-2022 走看看