jzoj1899. Pruning

Title description

Description
  gives a rooted tree. The tree has n nodes, which are marked as integers from 1 to n, and node 1 is the root node. The weight of the i-th (1≤i≤n) node is Wi. For node i, it has Ti children, which are Pi1, Pi2, ..., PiTi from left to right. In particular, if node i is a leaf node, Ti=0.
  We perform depth-first search (DFS) on the tree, and each point must visit each child in order from left to right to form a DFS sequence, denoted as Seq{Seq1,Seq2,...,Seqn}. For two leaf nodes a and b, we say that they are adjacent, if and only if there is no other leaf node c, c is between a and b in the DFS sequence. To put it another way, for leaf nodes a, b, c, denote Seqi=a, Seqj=b(i<j), there is no Seqk=c, so that i<k<j.
  Each pair of adjacent leaf nodes (a, b) has an influence value. The influence value is defined as the maximum point weight on the path from a to b (not including the nodes of a and b).
  The value of a tree is defined as the sum of the weights of all leaf nodes of this tree minus the influence value of each pair of adjacent leaf nodes.
  Of course, it would be too simple for you to count the value of this tree. Your goal is to do some pruning of the tree to maximize the value of the tree. The way of pruning is: if the children of a node are all leaf nodes, all of its children can be pruned.

Input
  line 1: n; line
  2...n+1: line i+1: Wi, Ti, Pi1, Pi2,..., PiTi.

Output
  line 1: The maximum value of this tree after modification.

Sample Input
1]
3
1 2 2 3
2 0
2 0

[Input example two]
8
4 2 2 3
2 3 4 5 6
3 2 7 8
5 0
4 0
2 0
1 0
1 0

Sample Output
[ Sample output 1]
3

【Output sample two】
6

Data Constraint

Hint
[Data Range]
  For 20%
  data, n≤20;
  for 60% data, n≤2000; for 100% data, n≤100000, 0<Wi≤10000.

answer

I did it n years ago but still didn’t cut it.
Every time I consider two adjacent leaves, transfer from u–lca to v–lca, and use max to transfer monotonously.

code

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

Guess you like

Origin blog.csdn.net/gmh77/article/details/99478827