P1364 医院设置(树型dp)

题目链接

思路

u为父节点,v为子节点如果把u点的医院改为v点,可以发现发现:
以v为根的子树的集合的所有人少走1步,但是另一集合的所有人要多走一步
设siz[i]表示以i为根节点的集合人的总数,dp[i]表示在i点设置医院的代价,则可转换成:dp[v]=dp[u]+siz[1]siz[v]siz[v]

代码:

// Problem: P1364 医院设置
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1364
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
using i128=__int128;
#define fi first
#define se second
#define pb push_back
#define eb emplace_back
#define inf 0x3f3f3f3f
#define infll 0x3f3f3f3f3f3f3f3fLL
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll>pll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a*b/gcd(a,b);}
ll power(ll x,ll y,ll p){ll res=1;x=x%p;while(y>0){if(y&1)res=(1ll*res*x)%p;y>>=1;x=(1ll*x*x)%p;}return res;}
ll mod_inv(ll x,ll p){return power(x,p-2,p);}
ll ceilDiv(ll n,ll m){if(n>=0)return (n+m-1)/m;else return n/m;}

void solve()
{
   int n;cin>>n;;
   vector<int>adj[n+1],a(n+1),siz(n+1),dp(n+1);
   for(int i=1;i<=n;i++)
   {
       cin>>a[i];
       int u,v;cin>>u>>v;
       if (u > 0) adj[i].push_back(u), adj[u].push_back(i);
       if (v > 0) adj[i].push_back(v), adj[v].push_back(i);
   }
   ll ans=1e18;
   function<void(int,int,int)>dfs=[&](int u,int fa,int dep)->void{
       siz[u]=a[u];
       for(const auto &v:adj[u])
        {
            if(v==fa)continue;
            dfs(v,u,dep+1);
            siz[u]+=siz[v];
        }
        dp[1]+=dep*a[u];
   };
   function<void(int,int)>dfs2=[&](int u,int fa)->void{
        
       for(const auto &v:adj[u])
        {
            if(v==fa)continue;
            dp[v]=dp[u]+siz[1]-2*siz[v];
            dfs2(v,u);
        }
        ans=min(ans,1ll*dp[u]);
   };
   dfs(1,0,0);
   dfs2(1,0);
   cout<<ans<<endl;
                                                        
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int _=1;
    //cin>>_;
    while(_--)solve();
    return 0;
}
posted @   书面  阅读(6)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示