• 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];
    	
    }
    
  • 相关阅读:
    Go 1.16新特性embed包及其使用
    PHP汉字转拼音的方法
    git diff ^M的消除
    转 C/C++中extern关键字详解
    idea安装步骤_IntelliJ IDEA 2019.3安装激活教程
    intellij idea 的全局搜索快捷键方法
    多边形面积计算及顶点顺逆时针方向判断
    凸多边形碰撞检测的分离轴算法(SAT)
    使用PCA方法创建OBB(oriented boundingbox)包围盒
    2021/12/08今日旧闻
  • 原文地址:https://www.cnblogs.com/-Iris-/p/13928883.html
Copyright © 2020-2023  润新知