E62 樹形DP P8677 [藍橋杯 2018 國 A] 採油

董晓發表於2024-10-10

影片連結:

P8677 [藍橋杯 2018 國 A] 採油 - 洛谷 | 電腦科學教育新生態 (luogu.com.cn)

// 樹形DP+貪心 O(nlogn)
#include<bits/stdc++.h>
#define N 100010
using namespace std;

vector<int> e[N];
int n,B[N],S[N],f[N],len;
struct man{int b,s;};
bool cmp(man x,man y){
  return x.b-x.s>y.b-y.s;
}

void dfs(int u,int fa){
  vector<man> t;
  t.push_back({B[u],S[u]});
  for(auto v:e[u]){
    if(v==fa) continue;
    dfs(v,u);
    S[u]+=S[v];
    t.push_back({f[v],S[v]});
  }
  sort(t.begin(),t.end(),cmp);
  for(auto i:t) f[u]+=i.s;
  f[u]+=max(t.back().b-t.back().s,0);
}
int main(){
  scanf("%d",&n);
  for(int i=1;i<=n;++i)scanf("%d",&B[i]);
  for(int i=1;i<=n;++i)scanf("%d",&S[i]);
  for(int i=2,a,b;i<=n;++i){
    scanf("%d%d",&a,&b);
    e[i].push_back(a),e[a].push_back(i);
    len+=b*2;
  }
  dfs(1,0);
  printf("%d %d\n",len,f[1]);
}

// 貪心 O(nlogn)
#include<bits/stdc++.h>
#define N 100010
using namespace std;

int n,B[N],S[N],t[N],len,ans;

int main(){
  scanf("%d",&n);
  for(int i=1;i<=n;++i)scanf("%d",&B[i]);
  for(int i=1;i<=n;++i)
    scanf("%d",&S[i]),ans+=S[i],t[i]=B[i]-S[i];
  for(int i=2,a,b;i<=n;++i){
    scanf("%d%d",&a,&b);
    len+=b*2;
  }
  sort(t+1,t+n+1);
  ans+=max(t[1],0);
  printf("%d %d\n",len,ans);
}