给定一棵树,该树包含以顶点1为根的N个顶点,一个数组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顶点数量的子树即五世的子树将被删除,而副反之亦然。
- 在树上应用“深度优先搜索”,对于每个未访问的顶点,检查其是否满足要求的条件。
- 为满足条件的每个顶点增加计数。对于不满足条件的顶点,无需遍历其子树,因为需要将其完全删除。
- 最后,在完全遍历树后打印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 deleteed
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 deleteed
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 deleteed
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 deleteed
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
5
时间复杂度: O(N)
辅助空间: O(N)