为了满足给定条件,需要从树中移除的最小叶子数
给定一个由N个顶点组成的树,以顶点1为根,一个数组val[]表示分配给每个顶点的值,一个数组cost[]表示树中每条边的成本,任务是找到最小数量要从给定树中移除的叶子的数量,使得:
For any vertex V, the sum of cost of edges to a vertex U in its subtree never exceeds val[U].
例子:
Input: N = 9, val[] = {88, 22, 83, 14, 95, 91, 98, 53, 11},
cost[] = { -1, 24, -8, 67, 64, 65, 12, -80, 8 }
Output: 5
Explanation:
The final graph after necessary removal of leaves is as follows:
Cost of edges (1, 4) = 67 > 14 (= val[4]). Therefore vertex 4 is removed.
Cost of edges (3, 2) = 24 > 22 (= val[2]). Therefore, vertex 2 is removed.
Cost of edges (1 –> 5 –> 7 –> 3 –> 9) = 64 + 12 + 8 – 8 = 76 > 11 (= val[9]). Therefore, vertex 9 needs to be deleted. Therefore, the entire subtree {9, 6, 8} is deleted.
Therefore, 5 nodes are removed from the tree.
Input: N = 7, val[] = { 11, 16, 27, 21, 15, 9, 11 },
cost[] = { 12, 1, 7, -17, -2, 2, 17}
edges[] = {{0, 3}, {0, 4}, {3, 6}, {4, 2}, {2, 1}, {2, 5}}
Output: 7
方法:
请按照以下步骤解决问题:
- 如果对于顶点V ,有一个顶点U使得边成本 (V –> U) 超过val[U] ,除了删除以U或V为根的整个子树之外别无选择。这是因为我们是只允许删除叶子顶点。
- 由于只能删除叶顶点,因此要删除U或V ,需要逐叶删除整个子树才能到达顶点U或V 。
- 为了尽量减少要删除的叶子数,贪婪地选择顶点数较少的子树,即如果 V 的子树的顶点数超过U的子树的顶点数,则V的子树将被删除,反之亦然反之亦然。
- 在树上应用深度优先搜索,对于每个未访问的顶点,检查它是否满足要求的条件。
- 增加满足条件的每个顶点的计数。对于不满足条件的顶点,不需要遍历其子树,需要将其全部删除。
- 最后,打印N – count ,在完全遍历树后,因为 count 包含不需要删除的顶点数。
以下是上述方法的实现:
C++
// C++ Program to find the minimum
// number of leaves to be deleted
#include
using namespace std;
// Stores the count of safe nodes
int cnt = 0;
// Function to perform DFS on the Tree
// to obtain the count of vertices that
// are not required to be deleted
void dfs(int* val, int* cost,
vector >& tr,
int u, int s)
{
// Update cost to reach
// the vertex
s = s + cost[u];
if (s < 0)
s = 0;
// If the vertex does not
// satisfy the condition
if (s > val[u])
return;
// Otherwise
cnt++;
// Traverse its subtree
for (int i = 0; i < tr[u].size(); i++) {
dfs(val, cost, tr, tr[u][i], s);
}
}
// Driver Code
int main()
{
int n = 9;
int val[] = { 88, 22, 83, 14, 95,
91, 98, 53, 11 };
int cost[] = { -1, 24, -8, 67, 64,
65, 12, -80, 8 };
// Stores the Tree
vector > tr(n + 1);
tr[0].push_back(3);
tr[0].push_back(4);
tr[4].push_back(6);
tr[6].push_back(2);
tr[2].push_back(1);
tr[2].push_back(8);
tr[8].push_back(5);
tr[5].push_back(7);
// Perform DFS
dfs(val, cost, tr, 0, 0);
// Print the number of nodes
// to be deleted
cout << n - cnt;
return 0;
}
Java
// Java Program to find the minimum
// number of leaves to be deleted
import java.util.*;
class GFG{
// Stores the count of safe nodes
static int cnt = 0;
// Function to perform DFS on the Tree
// to obtain the count of vertices that
// are not required to be deleted
static void dfs(int []val, int []cost,
Vector []tr,
int u, int s)
{
// Update cost to reach
// the vertex
s = s + cost[u];
if (s < 0)
s = 0;
// If the vertex does not
// satisfy the condition
if (s > val[u])
return;
// Otherwise
cnt++;
// Traverse its subtree
for (int i = 0; i < tr[u].size(); i++)
{
dfs(val, cost, tr, tr[u].get(i), s);
}
}
// Driver Code
public static void main(String[] args)
{
int n = 9;
int val[] = {88, 22, 83, 14, 95,
91, 98, 53, 11};
int cost[] = {-1, 24, -8, 67, 64,
65, 12, -80, 8};
// Stores the Tree
@SuppressWarnings("unchecked")
Vector []tr = new Vector[n + 1];
for (int i = 0; i < tr.length; i++)
tr[i] = new Vector();
tr[0].add(3);
tr[0].add(4);
tr[4].add(6);
tr[6].add(2);
tr[2].add(1);
tr[2].add(8);
tr[8].add(5);
tr[5].add(7);
// Perform DFS
dfs(val, cost, tr, 0, 0);
// Print the number of nodes
// to be deleted
System.out.print(n - cnt);
}
}
// This code is contributed by Princi Singh
Python3
# Python3 program to find the minimum
# number of leaves to be deleted
# Stores the count of safe nodes
cnt = 0
# Function to perform DFS on the Tree
# to obtain the count of vertices that
# are not required to be deleted
def dfs(val, cost, tr, u, s):
global cnt
# Update cost to reach
# the vertex
s = s + cost[u]
if (s < 0):
s = 0
# If the vertex does not
# satisfy the condition
if (s > val[u]):
return
# Otherwise
cnt += 1
# Traverse its subtree
for i in range(0, len(tr[u])):
dfs(val, cost, tr, tr[u][i], s)
# Driver Code
if __name__ == "__main__":
n = 9
val = [ 88, 22, 83, 14, 95,
91, 98, 53, 11 ]
cost = [ -1, 24, -8, 67, 64,
65, 12, -80, 8]
# Stores the Tree
tr = [[] for i in range(n + 1)]
tr[0].append(3)
tr[0].append(4)
tr[4].append(6)
tr[6].append(2)
tr[2].append(1)
tr[2].append(8)
tr[8].append(5)
tr[5].append(7)
# Perform DFS
dfs(val, cost, tr, 0, 0)
# Print the number of nodes
# to be deleted
print(n - cnt)
# This code is contributed by rutvik_56
C#
// C# Program to find the minimum
// number of leaves to be deleted
using System;
using System.Collections.Generic;
class GFG{
// Stores the count of safe nodes
static int cnt = 0;
// Function to perform DFS on the Tree
// to obtain the count of vertices that
// are not required to be deleted
static void dfs(int []val, int []cost,
List []tr,
int u, int s)
{
// Update cost to reach
// the vertex
s = s + cost[u];
if (s < 0)
s = 0;
// If the vertex does not
// satisfy the condition
if (s > val[u])
return;
// Otherwise
cnt++;
// Traverse its subtree
for (int i = 0; i < tr[u].Count; i++)
{
dfs(val, cost, tr, tr[u][i], s);
}
}
// Driver Code
public static void Main(String[] args)
{
int n = 9;
int []val = {88, 22, 83, 14, 95,
91, 98, 53, 11};
int []cost = {-1, 24, -8, 67, 64,
65, 12, -80, 8};
// Stores the Tree
List []tr = new List[n + 1];
for (int i = 0; i < tr.Length; i++)
tr[i] = new List();
tr[0].Add(3);
tr[0].Add(4);
tr[4].Add(6);
tr[6].Add(2);
tr[2].Add(1);
tr[2].Add(8);
tr[8].Add(5);
tr[5].Add(7);
// Perform DFS
dfs(val, cost, tr, 0, 0);
// Print the number of nodes
// to be deleted
Console.Write(n - cnt);
}
}
// This code is contributed by Rajput-Ji
Javascript
5
时间复杂度: O(N)
辅助空间: O(N)