当前位置: 首页 > news >正文

D. Paths on the Tree

Problem - 1746D - Codeforces

思路:先分析一下题意,根据第一条性质,每次只能够从1开始,而第二条性质则表明对于每个节点来说,经过这个节点的子节点的路径条数应该尽量均衡,最大值与最小值相差不能超过1,所以我们考虑,如果当前要选择k个路径,而当前节点有cnt个子节点,那么每个子节点应该至少经过k/cnt个,同时有k%cnt个需要经过k/cnt+1个,那么我们发现这个问题可以递归的解决,那么我们可以考虑用树形dp,我们将f[i][0]表示以i为根,并且经过ki个,f[i][1]表示以i为根并且经过ki+1个,那么对于叶子节点来说,f[i][0]=cost[i]*k,f[i][1]=cost[i]*(k+1),而对于非叶子节点来说,因为所有的子节点都至少经过ki个,所有我们先将所有子节点的f[j][0]求和为sum,令f[i][0]=f[i][1]=sum,那么我们还要再经过k%cnt个,那么我们就是挑几个子节点,然后让他变为f[j][1],那么我们可以将所有f[j][1]-f[j][0]排个序,按照降序排序,那么我们只需要将差值加上,就相当于这个变为了f[j][1],所以我们只需要求一下前k%cnt的和即可,这是对于f[i][0]来说,而对于f[i][1]来说,则还要多出来一次,那么我们只需要求和倒k%cnt+1即可,并且k%cnt+1按照相同的方法取最大的k%cnt+1个一定也是正确的,因为k%cnt最大为cnt-1个,加一为cnt个,正好等于子节点的个数,所以一定是合法的取法

// Problem: D. Paths on the Tree
// Contest: Codeforces - Codeforces Global Round 23
// URL: https://codeforces.com/problemset/problem/1746/D
// Memory Limit: 256 MB
// Time Limit: 3000 m#include<bits/stdc++.h>
#include<sstream>
#include<cassert>
#define fi first
#define se second
#define i128 __int128
using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int,int> PII;
const double eps=1e-7;
const int N=5e5+7 ,M=5e5+7, INF=0x3f3f3f3f,mod=1e9+7,mod1=998244353;
const long long int llINF=0x3f3f3f3f3f3f3f3f;
inline ll read() {ll x=0,f=1;char c=getchar();while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') {x=(ll)x*10+c-'0';c=getchar();} return x*f;}
inline void write(ll x) {if(x < 0) {putchar('-'); x = -x;}if(x >= 10) write(x / 10);putchar(x % 10 + '0');}
inline void write(ll x,char ch) {write(x);putchar(ch);}
void stin() {freopen("in_put.txt","r",stdin);freopen("my_out_put.txt","w",stdout);}
bool cmp0(int a,int b) {return a>b;}
template<typename T> T gcd(T a,T b) {return b==0?a:gcd(b,a%b);}
template<typename T> T lcm(T a,T b) {return a*b/gcd(a,b);}
void hack() {printf("\n----------------------------------\n");}int T,hackT;
int n,m,k;
int h[N],e[M],ne[M],idx;
ll f[N][2];
int cost[N];void add(int a,int b) {e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}void dfs(int u,int k) {f[u][0]=(ll)cost[u]*k;f[u][1]=(ll)cost[u]*(k+1);int cnt=0;for(int i=h[u];i!=-1;i=ne[i]) {int j=e[i];cnt++;}if(!cnt) return ;int a=k/cnt,b=k%cnt;vector<ll> vis;for(int i=h[u];i!=-1;i=ne[i]) {int j=e[i];dfs(j,a);f[u][0]+=f[j][0];f[u][1]+=f[j][0];vis.push_back(f[j][1]-f[j][0]);}sort(vis.begin(),vis.end(),[&](ll &a,ll &b){return a>b;});for(int i=0;i<b;i++) f[u][0]+=vis[i];for(int i=0;i<=b;i++) f[u][1]+=vis[i];
}void solve() {n=read(),k=read();memset(h,-1,sizeof(int)*(n+4));idx=0;for(int i=2;i<=n;i++) {int c=read();add(c,i);}for(int i=1;i<=n;i++) cost[i]=read();dfs(1,k);printf("%lld\n",f[1][0]);
}   int main() {// init();// stin();// ios::sync_with_stdio(false); scanf("%d",&T);// T=1; while(T--) hackT++,solve();return 0;       
}          

http://www.lryc.cn/news/161933.html

相关文章:

  • CocosCreator3.8研究笔记(九)CocosCreator 场景资源的理解
  • 大数据课程L1——网站流量项目的概述整体架构
  • 提升数据库安全小技巧,使用SSH配合开源DBeaver工具连接数据库
  • 信息安全技术概论-李剑-持续更新
  • java项目基于 SSM+JSP 的人事管理系统
  • 【Node.js】—基本知识点总结
  • Leetcode.174 地下城游戏
  • python实现adb辅助点击屏幕工具
  • 智能合约安全分析,针对 ERC777 任意调用合约 Hook 攻击
  • nodejs 爬虫 axios 异步爬虫 教程 【一】
  • Swift学习笔记三(Dictionary 篇)
  • javax.mail 遇到501 mail from address must be same as authorization user 的問題
  • 【Python】网络编程
  • 客户端开发常用框架
  • 数据分析综述
  • 区块链技术与应用 - 学习笔记2【密码学基础】
  • 制作Linux发行版安装镜像:复刻centos镜像安装ISO
  • 【复习socket】每天40min,我们一起用70天稳扎稳打学完《JavaEE初阶》——29/70 第二十九天
  • postgresql-常用数学函数
  • Docker实战技巧(一):常用命令与最佳实践
  • 使用CUDA计算GPU的理论显存带宽
  • npm install依赖冲突解决办法
  • 植物大战僵尸各种僵尸攻略
  • Scrum敏捷开发企业实战培训
  • uniapp 下拉框数据回显的问题
  • 使用php 获取时间今天、明天、昨天时间戳的详解
  • IIS解析漏洞复现
  • 生活随笔-吐槽篇
  • vscode debug python launch.json添加args不起作用
  • 信息化发展23