Another Crisis UVA-12186 (árbol dp)

Hace un par de años, comenzó una nueva crisis mundial que dejó a muchas personas con problemas económicos.
Algunos trabajadores de una empresa en particular están tratando de pedir un aumento en sus salarios.
La empresa tiene una jerarquía estricta, en la que cada empleado tiene exactamente un jefe directo, con la
excepción del propietario de la empresa que no tiene jefe. Los empleados que no son jefes de ningún otro
empleado se llaman trabajadores. El resto de los empleados y el propietario se llaman jefes.
Para solicitar un aumento salarial, un trabajador debe presentar una petición a su jefe directo. Por supuesto,
se alienta a cada jefe a tratar de hacer felices a sus subordinados con sus ingresos actuales, haciendo que el
beneficio de la empresa lo más alto posible Sin embargo, cuando al menos T por ciento de sus subordinados directos hayan
presentado una petición, ese jefe será presionado y no tendrá más remedio que presentar una petición él mismo a su propio
jefe directo. Cada jefe presenta como máximo 1 petición a su propio jefe directo, independientemente de cuántos de sus
subordinados le presentaron una petición. Un jefe solo contabiliza a sus subordinados directos (los que le presentaron
una petición y los que no lo hicieron) para calcular el porcentaje de presión.
Tenga en cuenta que un jefe puede tener tanto trabajadores como jefes como subordinados directos al mismo tiempo. Tal
jefe puede recibir peticiones de ambos tipos de empleados y de cada subordinado directo, independientemente de
su tipo, se contabilizará como 1 al verificar el porcentaje de presión.
Cuando un archivo de petición llega hasta el propietario de la empresa, se aumentan todos los salarios. El
sindicato de trabajadores está tratando desesperadamente de que eso suceda, por lo que deben convencer a muchos trabajadores para que
presenten una petición a su jefe directo.
Dada la jerarquía de la empresa y el parámetro T, debe averiguar el número mínimo de
trabajadores que tienen que presentar una petición para que el propietario reciba una petición.
Entrada
Hay varios casos de prueba. La entrada para cada caso de prueba se da exactamente en dos líneas. La primera línea
contiene dos enteros N y T (1 ≤ N ≤ 105
, 1 ≤ T ≤ 100), separados por un solo espacio. N indica
El número de empleados de la empresa (sin contar al propietario) y T es el parámetro descrito
anteriormente. Cada uno de los empleados se identifica con un número entero entre 1 y N. El propietario se identifica con
el número 0. La segunda línea contiene una lista de enteros separados por espacios individuales. El entero Bi
,
en la posición i de esta lista (a partir de 1), indica la identificación del jefe directo del empleado i
(0 ≤ Bi ≤ i - 1).
El último caso de prueba es seguido por una línea que contiene dos ceros separados por un solo espacio.
Salida
Para cada caso de prueba, envíe una sola línea que contenga un número entero único con el número mínimo de trabajadores
que necesitan presentar una petición para que el propietario de la empresa reciba una petición.
Muestra de entrada
3 100
0 0 0
3 50
0 0 0
14 60
0 0 1 1 2 2 2 5 7 5 7 5 7 5
0 0
Muestra de salida
3
2
5
Idea: Este tema no tiene nada que ver con dp, pero es más como un Codicioso. Para cada nodo, podemos calcular cuántos nodos debe informar. Supongamos que hay T, luego encuentre los T nodos secundarios más pequeños entre sus nodos secundarios, sume como la contribución de este nodo y luego devuelva esta contribución al nodo padre.
El código es el siguiente:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxx=1e5+100;
struct edge{
	int to,next;
}e[maxx<<1];
int head[maxx<<1],dp[maxx];
int n,T,tot;

inline void init()
{
	memset(head,-1,sizeof(head));
	for(int i=0;i<=n+1;i++) dp[i]=0;
	tot=0;
}
inline void add(int u,int v)
{
	e[tot].next=head[u],e[tot].to=v,head[u]=tot++;
}
inline int dfs(int u,int f)
{
	priority_queue<int,vector<int>,greater<int> >q;
	int sum=0;
	int flag=0;
	for(int i=head[u];i!=-1;i=e[i].next)
	{
		int to=e[i].to;
		if(to==f) continue;
		sum++;
		q.push(dfs(to,u));
		flag=1;
	}
	if(!flag) return 1;
	int num=((sum*T)%100==0?(sum*T)/100:(sum*T)/100+1);
	int ans=0;
	while(num)
	{
		ans+=q.top();
		q.pop();
		num--;
	}
	return ans;
}
int main()
{
	while(scanf("%d%d",&n,&T),n||T)
	{
		init();
		int x;
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&x);
			add(i,x);
			add(x,i);
		}
		int ans=dfs(0,-1);
		printf("%d\n",ans);
	}
	return 0;
}

Vamos duro, ( o ) / ~

674 artículos originales publicados · 130 alabanzas · 60,000+ vistas

Supongo que te gusta

Origin blog.csdn.net/starlet_kiss/article/details/105665855
Recomendado
Clasificación