P1364 医院设置

换根 dp[v]=dp[x]+siz[1]-2*siz[v];

/*
从一棵树中选取 一个结点 使 所有 点上权值 * dis 最短 
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
//#include<queue>
//#include<vector>
//#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=1e2+10 ;
const int mod=998244353;
const int inf=0x3f3f3f3f;

int n,w[maxn],head[maxn],to[maxn<<1],nxt[maxn<<1],tot;
int dep[maxn]={0,-1},siz[maxn],dp[maxn],ans=inf;

void add(int a,int b){
    to[++tot]=b,nxt[tot]=head[a],head[a]=tot;
}

void dfs1(int x,int faa)
{
    siz[x]=w[x];dep[x]=dep[faa]+1;
    for(int i=head[x];i;i=nxt[i]){
        int v=to[i];if(v==faa) continue;
        dfs1(v,x);
        siz[x]+=siz[v]; 
    }
    dp[1]+=dep[x]*w[x];
}

void dfs2(int x,int faa)
{
    for(int i=head[x];i;i=nxt[i])
    {
        int v=to[i];if(v==faa) continue;
        dp[v]=dp[x]+siz[1]-2*siz[v];
        ans=min(ans,min(dp[x],dp[v]));
        dfs2(v,x);
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++){
        int a,b;cin>>w[i]>>a>>b;
        if(a) add(i,a),add(a,i);
        if(b) add(i,b),add(b,i);
    }
    
    dfs1(1,1);
    dfs2(1,1);
    
    cout<<ans<<'\n';
    return 0;
}

 

posted @ 2023-09-29 16:30  JMXZ  阅读(6)  评论(0)    收藏  举报