CodeForces - 1436D Bandit in a City

题目链接

https://vjudge.net/problem/CodeForces-1436D

题意

n个节点,n-1条单向边,连通图,每一个点有一定的人数,人们从1点开始,沿单向路走动,歹徒从1点开始,沿道路追赶,追到无路可走停止,歹徒知道所有人的位置,整张图的情况,人们也知道歹徒位置,人可以相互配合,问人和歹徒都选择最优策略情况下,歹徒能追到的人数

思路

我们先跑一遍dfs处理每个节点为根的子树的总权值和叶子节点个数。

当最理想情况下,某一根节点的全部人(包含子节点的人)都平均的走向不同的路,最终歹徒追到的人是总权值/叶子节点个数

但因为子节点都提前有一定的人数,且路是单向路,不能回走,所以可能存在某一个子节点人已经非常多,无论怎么分配根节点的人员移动,都无法达到平均的情况。

对于这种情况,歹徒一定会走向那一条无法被平均的路,我们记这个节点为x,那么我们最佳策略是全部走其他的路,不向x分配任何一个人员。那以当前节点为根的数的答案就是递归的求以x节点为根的子树的答案。

因为所有节点最终都会走向叶子节点,叶子节点一定是可以平均分的,那么最终所有情况都会变成最理想情况。

我们再考虑以x为根的情况,最理想情况求取的答案一定是小于等于不能平均的答案的,于是我们可以遍历每一个节点,按照最理想情况求值,最终答案取max即可。

代码

#include<cstdio>
#include<iostream>
#include<iomanip>
#include<map>
#include<string>
#include<queue>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib> 
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define endl "\n"
#define int long long
using namespace std;

	typedef long long ll;
	const int inf=0x3f3f3f3f;
	const int maxn=300010;
	const int maxe=300010;
	int head[maxn],cnt;
	struct Edge{
    
    
		int v;
		int w;
		int next;
	}edge[maxe];
	int out[maxn];
	int sn[maxn];
	ll sm[maxn];
	int va[maxn];
	int ans=inf;
	inline void add(int u,int v,int w=0){
    
    
  		edge[cnt].v=v;
		edge[cnt].w=w;
		edge[cnt].next=head[u];
		head[u]=cnt++;
	}
	void init(){
    
    
		memset(head,-1,sizeof(head));
		cnt=0;
		return ;	
	}
	void dfs(int x){
    
    
	//	if(x==-1)
	//		return 1;
		int total=0; 
    	int son=0;
    	bool bl=0;
		for(int i=head[x];~i;i=edge[i].next){
    
    
    		dfs(edge[i].v);
    		bl=1;
    		son+=sn[edge[i].v];
    		total+=sm[edge[i].v];
		}
		sm[x]=total+va[x];
		if(!bl)
			sn[x]=1;
		else
			sn[x]=son;
	}
	signed main(){
    
    	
		IOS
    	init();
    	int n;
		cin>>n;
    	for(int i=2;i<=n;i++){
    
    
    		int tmp;
    		cin>>tmp;
    		add(tmp,i);
    		out[tmp]++;
		}
		for(int i=1;i<=n;i++){
    
    
			cin>>va[i];
		}
		dfs(1);
		int ans=-inf;
		for(int i=1;i<=n;i++){
    
    
			int t=ceil((double)sm[i]/sn[i]);
			ans=max(ans,t);
		}
    	cout<<ans<<endl;
    	return 0;
	}

猜你喜欢

转载自blog.csdn.net/TheSunspot/article/details/109300647