CodeForces - 1436D Bandit in a City

Topic link

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

Title

n nodes, n-1 one-way edges, connected graph, each point has a certain number of people, people start at 1 point and walk along the one-way road, the gangsters start at 1 point, chasing along the road, until there is nowhere to go Stop walking, the gangster knows the location of everyone, the whole picture, people also know the gangster’s location, people can cooperate with each other, and ask the number of gangsters that can be chased when both the man and the gangster choose the best strategy.

Ideas

We first run dfs to process the total weight of the subtree rooted at each node and the number of leaf nodes.

In the most ideal situation, all the people at a root node (including the child nodes) will go to different paths on average, and the person chased by the criminals is the total weight/number of leaf nodes

However, because the child nodes have a certain number of people in advance, and the road is a one-way road, which cannot go back, there may be a large number of people in a child node. No matter how the personnel movement of the root node is allocated, the average situation cannot be reached.

In this case, the gangster will definitely go to the path that cannot be averaged. We denote this node as x, then our best strategy is to take all other paths and not assign any person to x. The answer to the number rooted at the current node is to recursively find the answer to the subtree rooted at the x node.

Because all nodes will eventually go to the leaf nodes, the leaf nodes must be evenly scored, so in the end all situations will become the most ideal situation.

Let's consider the case where x is the root. The ideal answer must be less than or equal to the unaveraged answer, so we can traverse each node and evaluate according to the most ideal situation. The final answer can be max.

Code

#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;
	}

Guess you like

Origin blog.csdn.net/TheSunspot/article/details/109300647