当前位置:网站首页>Infected Tree(树形dp)
Infected Tree(树形dp)
2022-07-05 08:22:00 【山中一扶苏】
原题链接
题目描述
Misha发现了一棵二叉树,它的顶点编号从到。二叉树是一种包含顶点和边的无环连通双向图。每个顶点最多有一个度,而根顶点是有个数的顶点,它最多有一个度。
不幸的是,树根被感染了。
以下过程发生的次数:
Misha要么选择一个未被感染(也没有被删除)的顶点,并删除它,所有的边都有一个端点在这个顶点,或者什么都不做。
然后,感染扩散到由一条边连接到已感染顶点的每个顶点(所有已感染顶点仍然是感染的)。
由于Misha没有太多时间思考,请告诉他他可以从感染中拯救的最大顶点数是多少(注意删除的顶点不计入保存)
输入样例
4
2
1 2
4
1 2
2 3
2 4
7
1 2
1 5
2 3
2 4
5 6
5 7
15
1 2
2 3
3 4
4 5
4 6
3 7
2 8
1 9
9 10
9 11
10 12
10 13
11 14
11 15
输出样例
0
2
2
10
算法
(树形dp)
本题可以通过维护一个 dp 数组可以快速统计 每一个点作为根节点保留左子树或者保留右子树的最大保留人数 ,从而最后通过 dfs 过程中更新迭代,生成最后需要的答案。
值得注意的是题目的删除点及其子树的顺序是从根到枝叶,但在树形 dp 的统计过程中应该从枝叶到根进行 dp 数组统计,因为最后保留的都是每一层的枝叶,一般的树形 dp 业主要是以这样的方式统计
状态方程:
dp[u][0] = sum[l[u]] - 1 + max(dp[r[u]][1],dp[r[u]][0]);//保留左子树
dp[u][1] = sum[r[u]] - 1 + max(dp[l[u]][1],dp[l[u]][0]);//保留右子树
C++ 代码
时间复杂度 O ( n ) O(n) O(n)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int N = 3e5 + 10;
vector<int> g[N];
int dp[N][2];//每一个点作为根节点保留左子树或者保留右子树的最大保留人数
int sum[N],l[N],r[N];//以u为根节点能够保留的总人数,u节点的左节点与右节点
void pre_dfs(int u,int fa)//预处理
{
sum[u] = 1;
for (int i = 0;i < g[u].size();i ++ ) {
int j = g[u][i];
if (j == fa) continue;
//经典代码,利用dfs的规律分别指定左右节点
if (l[u] == 0) l[u] = j;
else r[u] = j;
pre_dfs(j,u);
sum[u] += sum[j];
}
}
void dfs(int u,int fa)
{
dp[u][1] = dp[u][0] = 0;//初始化
for(int i = 0;i < g[u].size();i ++ ){
int j = g[u][i];
if (j == fa) continue;
dfs(j,u);
//最后进行dp统计
dp[u][0] = sum[l[u]] - 1 + max(dp[r[u]][1],dp[r[u]][0]);//save left subtree
dp[u][1] = sum[r[u]] - 1 + max(dp[l[u]][1],dp[l[u]][0]);//save right subtree
}
}
int main()
{
int t;
cin >> t;
while (t -- ) {
int n;
cin >> n;
int m = n - 1;
for (int i = 1;i <= n;i ++ ) {
sum[i] = l[i] = r[i] = 0;
g[i].clear();
}
for (int i = 0;i < m;i ++ ) {
int u,v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
pre_dfs(1,1);
dfs(1,1);
cout << max(dp[1][0],dp[1][1]) << '\n';
}
return 0;
}
边栏推荐
- STM32 single chip microcomputer -- debug in keil5 cannot enter the main function
- Shape template matching based on Halcon learning [viii] PM_ multiple_ models. Hdev routine
- Semiconductor devices (III) FET
- 【三层架构】
- 2020-05-21
- Carrier period, electrical speed, carrier period variation
- Solutions to compilation warnings in Quartus II
- After installing the new version of keil5 or upgrading the JLINK firmware, you will always be prompted about the firmware update
- Count the number of inputs (C language)
- Sql Server的存儲過程詳解
猜你喜欢
Class of color image processing based on Halcon learning_ ndim_ norm. hdev
Classic application of MOS transistor circuit design (2) - switch circuit design
leetcode - 445. 两数相加 II
Management and use of DokuWiki
Management and use of DokuWiki (supplementary)
C language # and #
Shape template matching based on Halcon learning [VII] reuse_ model. Hdev routine
Charge pump boost principle - this article will give you a simple understanding
Simple design description of MIC circuit of ECM mobile phone
Relationship between line voltage and phase voltage, line current and phase current
随机推荐
Brief discussion on Buck buck circuit
Several important parameters of LDO circuit design and type selection
Naming rules for FreeRTOS
STM32 outputs 1PPS with adjustable phase
Google sitemap files for rails Projects - Google sitemap files for rails projects
Bootloader implementation of PIC MCU
Bluetooth hc-05 pairing process and precautions
Talk about the function of magnetic beads in circuits
Introduction of air gap, etc
Sword finger offer 09 Implementing queues with two stacks
C WinForm [view status bar -- statusstrip] - Practice 2
Carrier period, electrical speed, carrier period variation
QEMU demo makefile analysis
Stm32--- systick timer
[trio basic tutorial 18 from introduction to proficiency] trio motion controller UDP fast exchange data communication
Why is 1900 not a leap year
Management and use of DokuWiki (supplementary)
Void* C is a carrier for realizing polymorphism
实例008:九九乘法表
Tailq of linked list