考虑最后这棵二叉树的结构,不难发现被移动的点在原树或新树中构成的都是若干棵完整的子树

(若$x$被移动,则$x$在原树或新树的子树中所有点都会被移动)

先在原树中考虑此问题,对于每一棵由被移动的点所构成的极大的子树,将子树大小累加到这棵子树根的父亲的权值$a_{i}$上(初始为0),将深度和累加到答案上(深度定义为到这棵子树根的距离+1)

类似地,对新树也执行此操作,得到权值$b_{i}$(注意新树中深度的定义应该去掉"+1")

下面,问题即要不断选择$(x,y)\in E$(注意一条边有两种选法),使得$a_{x}$增加1且$a_{y}$减小1,并且最小化操作次数,最终将答案加上这个操作次数

考虑每一条边被使用的次数,不难发现最小操作次数即$\sum_{u=1}^{n}\abs{\sum_{v在u的子树中}(a_{v}-b_{v})}$

对于$a_{i}$和$b_{i}$的选择,即令$f_{i,j}$表示以$i$为根的子树中,强制$i$不被移动且$\sum_{v在i的子树中}(b_{v}-a_{v})=j$的最小答案(仅考虑子树内的贡献),下面来考虑转移——

儿子分为被移动和未被移动的,都可以用背包处理,且还需要求出第2类的数量(不超过2),然后再枚举$b_{i}$并将对应的代价加入其中(显然是完全二叉树)

由于$\sum_{v在i的子树中}(b_{v}-a_{v})$并不保证是$\le sz_{v}$的,因此背包的复杂度为$o(n^{2})$

总复杂度即$o(tn^{3})$,可以通过

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 105
4 struct Edge{
5 int nex,to;
6 }edge[N<<1];
7 int E,t,n,x,y,sum[N],head[N],sz[N],tot[N],g[N][3],gg[N][3],f[N][N];
8 void add(int x,int y){
9 edge[E].nex=head[x];
10 edge[E].to=y;
11 head[x]=E++;
12 }
13 void dfs(int k,int fa){
14 sz[k]=1,tot[k]=0;
15 for(int i=head[k];i!=-1;i=edge[i].nex)
16 if (edge[i].to!=fa){
17 dfs(edge[i].to,k);
18 sz[k]+=sz[edge[i].to];
19 tot[k]+=tot[edge[i].to];
20 }
21 tot[k]+=sz[k];
22 memset(g,0x3f,sizeof(g));
23 g[0][0]=0;
24 for(int i=head[k];i!=-1;i=edge[i].nex)
25 if (edge[i].to!=fa){
26 memcpy(gg,g,sizeof(g));
27 for(int j=n;j>=0;j--)
28 for(int p=0;p<3;p++)g[j][p]+=tot[edge[i].to];
29 for(int l=0;l<=n;l++)
30 for(int j=l;j<=n;j++)
31 for(int p=1;p<3;p++)g[j][p]=min(g[j][p],gg[j-l][p-1]+f[edge[i].to][l]);
32 }
33 for(int i=0;i<=n;i++){
34 f[k][i+1]=min(min(g[i][0],g[i][1]),g[i][2]);
35 for(int j=1;j<=i;j++){
36 f[k][i+1]=min(f[k][i+1],g[i-j][0]+sum[j>>1]+sum[j+1>>1]);
37 f[k][i+1]=min(f[k][i+1],g[i-j][1]+sum[j]);
38 }
39 }
40 for(int i=0;i<=n;i++)f[k][i]+=abs(i-sz[k]);
41 }
42 int main(){
43 for(int i=1;i<N;i++)sum[i]=sum[i>>1]+sum[i-1>>1]+i-1;
44 scanf("%d",&t);
45 while (t--){
46 scanf("%d",&n);
47 E=0;
48 memset(head,-1,sizeof(head));
49 for(int i=1;i<n;i++){
50 scanf("%d%d",&x,&y);
51 add(x,y);
52 add(y,x);
53 }
54 dfs(1,0);
55 printf("%d\n",f[1][n]);
56 }
57 return 0;
58 }

[hdu7042]二叉树的更多相关文章

  1. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  2. 二叉树的递归实现(java)

    这里演示的二叉树为3层. 递归实现,先构造出一个root节点,先判断左子节点是否为空,为空则构造左子节点,否则进入下一步判断右子节点是否为空,为空则构造右子节点. 利用层数控制迭代次数. 依次递归第二 ...

  3. c 二叉树的使用

    简单的通过一个寻找嫌疑人的小程序 来演示二叉树的使用 #include <stdio.h> #include <stdlib.h> #include <string.h& ...

  4. Java 二叉树遍历右视图-LeetCode199

    题目如下: 题目给出的例子不太好,容易让人误解成不断顺着右节点访问就好了,但是题目意思并不是这样. 换成通俗的意思:按层遍历二叉树,输出每层的最右端结点. 这就明白时一道二叉树层序遍历的问题,用一个队 ...

  5. 数据结构:二叉树 基于list实现(python版)

    基于python的list实现二叉树 #!/usr/bin/env python # -*- coding:utf-8 -*- class BinTreeValueError(ValueError): ...

  6. [LeetCode] Path Sum III 二叉树的路径和之三

    You are given a binary tree in which each node contains an integer value. Find the number of paths t ...

  7. [LeetCode] Find Leaves of Binary Tree 找二叉树的叶节点

    Given a binary tree, find all leaves and then remove those leaves. Then repeat the previous steps un ...

  8. [LeetCode] Verify Preorder Serialization of a Binary Tree 验证二叉树的先序序列化

    One way to serialize a binary tree is to use pre-oder traversal. When we encounter a non-null node, ...

  9. [LeetCode] Binary Tree Vertical Order Traversal 二叉树的竖直遍历

    Given a binary tree, return the vertical order traversal of its nodes' values. (ie, from top to bott ...

随机推荐

  1. 在昨天夜黑风高的晚上,我偷了隔壁老王的Python入门课件,由浅入深堪称完美!

    隔壁老王是一个资深码农,就业教育事业的秃顶之才昨天我下楼打酱油,看他迎面走来,满目春光我好奇的问道:老王,有什么好事,隔壁小花叫你上门了吗?老王:秘密!!我心想:哎呦~不错啊半晚之时,连猫狗都睡着了, ...

  2. Rclone使用教程 - 挂载Onedrive和谷歌网盘

    1. 介绍 Rclone 是一个用于多个云平台之间同步文件和目录的命令行工具,其支持多种运营商网盘. 官网网址:https://rclone.org 开源地址:https://github.com/n ...

  3. SoapUI入门实例

    一.Soapui介绍 WSDL(Web Services Description Language)就是这样一个基于XML的语言,用于描述Web Service及其函数.参数和返回值.它是WebSer ...

  4. PTA数据结构 习题2.1 简单计算器 (20分)

    习题2.1 简单计算器 (20分) 模拟简单运算器的工作.假设计算器只能进行加减乘除运算,运算数和结果都是整数,四种运算符的优先级相同,按从左到右的顺序计算. 输入格式: 输入在一行中给出一个四则运算 ...

  5. 3.2 Dependencies of the Projects in the Solution 解决方案中项目间的依赖项

    3.2 Dependencies of the Projects in the Solution 解决方案中项目间的依赖项 The diagram below shows the essential ...

  6. 错误 Unresolved reference 'AF_INET' 解决办法

    错误代码如下: import socketserer_socket = socket.socket(AF_INET, SOCK_DGAM) 错误信息: 原因分析: 1.AF_INET,SOCK_DGA ...

  7. FastAPI 学习之路(四十六)WebSockets(二)

    上一篇文章,我们分享了WebSockets一些入门的,我们这节课,在原来的基础上,对于讲解的进行一个演示.我们最后分享了依赖token等.首先我们对上次的代码进行调整. 我们之前分享FastAPI 学 ...

  8. Spring Cloud Alibaba 的服务注册与发现

    Spring Cloud Alibaba 服务发现例子 一.需求 1.提供者完成的功能 2.消费者完成的功能 3.可以附加的额外配置 二.实现步骤 1.总的依赖引入 2.服务提供者和发现者,引入服务发 ...

  9. 2021.8.18 NKOJ周赛总结

    两个字总结:安详 T1: NKOJ-6179 NP问题 问题描述: p6pou在平面上画了n个点,并提出了一个问题,称为N-Points问题,简称NP问题. p6pou首先在建立的平面直角坐标系,并标 ...

  10. cf18B Platforms(仔细谨慎题)

    题意: In one one-dimensional world there are n platforms. Platform with index k (platforms are numbere ...