zoukankan      html  css  js  c++  java
  • CF1436D Bandit in a City 题解

    思路

    一道CF题
    看题目很明显可以使用二分,但又想不到很好的judging函数
    所以考虑动态规划
    先考虑假如完全理想均分
    那么每个叶子节点可以被分到(lceilfrac{size[u]}{leaf[u]} ceil)
    (为什么是上取整(?)仔细想想
    那么现在我们能进行分配的只有当前节点权值
    如果每个子节点都小于(lceilfrac{size[u]}{leaf[u]} ceil)
    那么就意味着我们可以对每个点稍微加上那么点权值,使得它们都达到(lceilfrac{size[u]}{leaf[u]} ceil)左右
    那么若存在最大点大于(lceilfrac{size[u]}{leaf[u]} ceil),我们肯定不会再向这个点加权,
    再加权只会让答案变得更劣,所以要尽量"浪费"掉手中的权值,

    动态规划方程

    (mxn[x]以x为子树中最大的叶子节点,size[x]x子树中的权值和,leaf[x]x子树中的叶节点个数)

    [mxn[x] = max({mxn[y] , lceilfrac{size[u]}{leaf[u]} ceil }) ]

    Code

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    
    using namespace std;
    
    #define int long long 
    
    const int p=2e5+5;
    
    template<typename _T>
    inline void read(_T &x)
    {
    	x=0;char s=getchar();int f=1;
    	while(s<'0'||'9'<s){f=1;if(s=='-')f=-1;s=getchar();}
    	while('0'<=s&&s<='9'){x=(x<<3)+(x<<1)+s-'0';s=getchar();}
    	x*=f;
    }
    
    int head[p],nxt[p*2],ver[p*2];
    int point[p];
    int tit;
    
    int leaf[p],mxn[p],size[p];
    
    inline void add(int x,int y)
    {
    	ver[++tit] = y;
    	nxt[tit] = head[x];
    	head[x] = tit;
    }
    
    inline void dfs(int now,int fa)
    {
    	size[now] = point[now];
    	int cnt=0;
    	
    	for(int v,i=head[now];i;i=nxt[i])
    	{
    		if(ver[i] == fa) continue;
    		v=ver[i];
    		dfs(v,now);
    		size[now] += size[v];
    		leaf[now] += leaf[v];
    		mxn[now] = max(mxn[now] , mxn[v]);
    		cnt++;
    	}
    	
    	if(cnt == 0) mxn[now] = point[now],leaf[now]=1;
    	
    }
    
    inline void bfs(int now,int fa)
    {
    	for(int i=head[now];i;i=nxt[i])
    	{
    		int v=ver[i];
    		if(v == fa) continue;
    		bfs(v,now);
    		mxn[now] = max(mxn[now] , max(mxn[v] , (int)ceil((double)size[now]/leaf[now])));
    	}
    }
    
    signed main()
    {
    	
    	int n;
    	
    	read(n);
    	
    	for(int i=2,pi;i<=n;i++)
    	{
    		read(pi);
    		
    		add(i,pi);
    		add(pi,i);
    	}
    	
    	for(int i=1;i<=n;i++) read(point[i]);
    	
    	dfs(1,0);
    	
    	bfs(1,0);
    	
    	cout<<mxn[1];
    	
    }
    
  • 相关阅读:
    Promises-小程序购物车结算
    微信小程序支付
    微信企业付款到零钱
    Ubuntu16 远程连接MySQL
    MySQL数据库中文变问号
    Ubuntu开启ApacheRewrite功能
    大数据2018:云存储已在客观层面扮演数据湖角色
    地平线发布兼具本地端抓拍与识别功能的嵌入式AI摄像机
    肥皂遇上黑科技!异味统统都走开!
    LG新专利或用于移动VR,可通过外部旋钮调节显示屏与透镜
  • 原文地址:https://www.cnblogs.com/-Iris-/p/13928883.html
Copyright © 2011-2022 走看看