jzoj1899. Poda

Descripción del Título

La descripción
  da un árbol enraizado. El árbol tiene n nodos, que están marcados como números enteros de 1 an, y el nodo 1 es el nodo raíz. El peso del nodo i-ésimo (1≤i≤n) es Wi. Para el nodo i, tiene Ti hijos, que son Pi1, Pi2, ..., PiTi de izquierda a derecha. En particular, si el nodo i es un nodo hoja, Ti = 0.
  Realizamos una búsqueda en profundidad (DFS) en el árbol, y cada punto debe visitar a cada niño en orden de izquierda a derecha para formar una secuencia DFS, denotada como Seq {Seq1, Seq2, ..., Seqn}. Para dos nodos hoja ayb, decimos que son adyacentes, si y solo si no hay otro nodo hoja c, c está entre ayb en la secuencia DFS. Para decirlo de otra manera, para los nodos hoja a, b, c, denote Seqi = a, Seqj = b (i <j), no hay Seqk = c, de modo que i <k <j.
  Cada par de nodos de hojas adyacentes (a, b) tiene un valor de influencia. El valor de influencia se define como el peso máximo en puntos en la ruta de aab (sin incluir los nodos de ayb).
  El valor de un árbol se define como la suma de los pesos de todos los nodos de hojas de este árbol menos el valor de influencia de cada par de nodos de hojas adyacentes.
  Por supuesto, sería demasiado simple para usted contar el valor de este árbol. Su objetivo es podar un poco el árbol para maximizar el valor del árbol. La forma de podar es: si los hijos de un nodo son todos nodos de hojas, todos sus hijos pueden podarse.


  Línea de entrada 1: n; línea
  2 ... n + 1: línea i + 1: Wi, Ti, Pi1, Pi2, ..., PiTi.


  Línea de salida 1: el valor máximo de este árbol después de la modificación.

Entrada de muestra
1]
3
1 2 2 3
2 0
2 0

[Ejemplo de entrada dos]
8
4 2 2 3
2 3 4 5 6
3 2 7 8
5 0
4 0
2 0
1 0
1 0

Salida de muestra
[ Salida de muestra 1]
3

【Muestra de salida dos】
6

Restricción de datos

Sugerencia
[Rango de datos]
  Para 20% de
  datos, n≤20;
  para 60% de datos, n≤2000; para 100% de datos, n≤100000, 0 <Wi≤10000.

responder

Lo hice hace n años pero todavía no lo corté.
Cada vez que considero dos hojas adyacentes, transfiero de u – lca a v – lca, y uso max para transferir monótonamente.

código

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;

int a[100001][2];
int ls[100001];
int son[100001];
int w[100001];
int W[100001];
int fa[100001];
int bg[100001];
int ed[100001];
int d[100001];
int f[100001];
int b[100001];
int c[100001];
int sum[100002];
int Sum[100002];
int n,m,i,j,k,l,len,tot,l1,l2,mx,ans;

void New(int x,int y)
{
    
    
	++len;
	a[len][0]=y;
	a[len][1]=ls[x];
	ls[x]=len;
}

void dfs(int t)
{
    
    
	int i;
	
	if (!ls[t])
	d[++tot]=t;
	
	bg[t]=++j;
	
	for (i=ls[t]; i; i=a[i][1])
	{
    
    
		fa[a[i][0]]=t;
		dfs(a[i][0]);
	}
	
	ed[t]=j;
}

bool pd(int x,int y)
{
    
    
	return bg[x]<=bg[y] && ed[y]<=ed[x];
}

bool swap(int &x,int &y)
{
    
    
	int z=x;
	x=y;
	y=z;
}

int main()
{
    
    
//	freopen("cut2.in","r",stdin);
//	freopen("S8_13_3.in","r",stdin);
	
	scanf("%d",&n);
	fo(i,1,n)
	{
    
    
		scanf("%d%d",&w[i],&m);
		fo(j,1,m)
		scanf("%d",&son[j]);
		
		fd(j,m,1)
		New(i,son[j]);
	}
	
	j=0;
	dfs(1);
	
	i=d[1];
	while (i)
	{
    
    
		f[i]=w[i];
		i=fa[i];
	}
	
	fo(l,2,tot)
	{
    
    
		l1=0;
		l2=0;
		
		i=d[l-1];
		while (!pd(i,d[l]))
		{
    
    
			b[++l1]=i;
			i=fa[i];
		}
		
		i=d[l];
		while (!pd(i,d[l-1]))
		{
    
    
			c[++l2]=i;
			i=fa[i];
		}
		
		fd(i,l1/2,1) swap(b[i],b[l1-i+1]);
		fd(i,l2/2,1) swap(c[i],c[l2-i+1]);
		
		b[0]=fa[b[1]];
		sum[0]=-2133333333;
		W[0]=w[b[0]];
		fo(i,1,l1)
		{
    
    
			sum[i]=max(sum[i-1],f[b[i]]);
			W[i]=max(W[i-1],w[b[i]]);
		}
		
		Sum[l1+1]=-2133333333;
		fd(i,l1,1)
		Sum[i]=max(Sum[i+1],f[b[i]]-W[i-1]);
		
		mx=w[b[0]];
		j=1;
		fo(i,1,l2)
		{
    
    
			while (j<l1 && w[b[j]]<=mx)
			++j;
			
			f[c[i]]=max(sum[j]-mx,Sum[j+1])+w[c[i]];
			
			mx=max(mx,w[c[i]]);
		}
	}
	
	i=d[tot];
	while (i)
	{
    
    
		ans=max(ans,f[i]);
		i=fa[i];
	}
	
	printf("%d\n",ans);
}

Supongo que te gusta

Origin blog.csdn.net/gmh77/article/details/99478827
Recomendado
Clasificación