CodeForces - 1436D Bandit en una ciudad

Enlace de tema

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

Título

n nodos, n-1 bordes unidireccionales, gráfico conectado, cada punto tiene un cierto número de personas, las personas comienzan en 1 punto y caminan por el camino de un solo sentido, los gánsteres comienzan en 1 punto, persiguiendo a lo largo del camino, hasta que no hay ningún lugar adonde ir Deja de caminar, el gángster conoce la ubicación de todos, la imagen completa, la gente también conoce la ubicación del gángster, la gente puede cooperar entre sí y preguntar el número de gángsters que pueden perseguir tanto al hombre como al gángster para elegir la mejor estrategia.

Ideas

Primero ejecutamos dfs para procesar el peso total del subárbol enraizado en cada nodo y el número de nodos hoja.

En el caso ideal, todas las personas en un nodo raíz (incluidos los nodos secundarios) irán a diferentes carreteras en promedio, y las personas perseguidas por los delincuentes son el peso total / número de nodos hoja.

Sin embargo, debido a que los nodos secundarios tienen un cierto número de personas de antemano y la carretera es un camino de un solo sentido, que no puede retroceder, puede haber una gran cantidad de personas en un nodo secundario y, independientemente de cómo se asigne el movimiento de personal del nodo raíz, no se puede alcanzar la situación promedio.

En este caso, el gángster definitivamente irá al camino que no se puede promediar. Denotamos este nodo como x, entonces nuestra mejor estrategia es tomar todos los demás caminos y no asignar ninguna persona a x. La respuesta al número arraigado en el nodo actual es encontrar de forma recursiva la respuesta al subárbol arraigado en el nodo x.

Debido a que todos los nodos eventualmente irán a los nodos hoja, los nodos hoja deben puntuarse uniformemente, luego, eventualmente, todas las situaciones se convertirán en la situación más ideal.

Consideremos el caso donde x es la raíz. La respuesta ideal debe ser menor o igual que la respuesta no promediada, para que podamos atravesar cada nodo y evaluar de acuerdo con la situación más ideal. La respuesta final puede ser máx.

Código

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

Supongo que te gusta

Origin blog.csdn.net/TheSunspot/article/details/109300647
Recomendado
Clasificación