标签:set and cin main cout space include 就是 name
https://codeforces.com/problemset/problem/1436/D
这题就是让村名尽可能集中在叶子上,但是可能叶子上本来就有很多村民,就是这样。
假设
1. mx[x]为在x点可以抓到的最多的人
2. chal[x]为 在x点还差chal[x]人就可以让x下面所有叶子都有x个人
大致就是树形dp的写法了
具体看代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 3e5+11;
typedef long long ll;
vector<int>G[maxn];
ll list[maxn];
ll mx[maxn];//最大值
ll chal[maxn];//缺几个补上
ll ans[maxn];
ll cns[maxn];
void add(int x,int y){
G[x].push_back(y);
}
int dfs(int x,int fa){
ll siz = 0 ;
for(int i=0;i<G[x].size();i++){
int p = G[x][i];
if(p == fa) continue;
dfs(p,x);
cns[x] += cns[p];
siz++;
mx[x] = max(mx[x],mx[p]);//最大值
chal[x] += chal[p];
}
if(siz == 0){
mx[x] = list[x];
cns[x] = 1;
return 0;
}
siz = cns[x];
for(int i=0;i<G[x].size();i++){
int p = G[x][i];
if(p == fa) continue;
chal[x] += (mx[x] - mx[p])*cns[p];
}
if(list[x] > chal[x]){
list[x] -= chal[x];
chal[x] = 0;
mx[x] += list[x] / siz;
if(list[x] % siz != 0){
mx[x] ++;
chal[x] = siz - list[x] % siz;
}
list[x] = 0;
}
else{
chal[x] -= list[x];
list[x] = 0;
}
return 0;
}
int main(){
int n;
cin>>n;
int x,y;
for(int i=2;i<=n;i++){
cin>>x;
add(x,i);
add(i,x);
}
for(int i=1;i<=n;i++){
cin>>list[i];
}
dfs(1,-1);
cout<<mx[1]<<endl;
return 0;
}
CodeForces - 1436D Bandit in a City
标签:set and cin main cout space include 就是 name
原文地址:https://www.cnblogs.com/lesning/p/13886597.html