📌  相关文章
📜  为了满足给定条件,需要从树上删除的最少叶子数

📅  最后修改于: 2021-05-06 08:01:42             🧑  作者: Mango

给定一棵树,该包含以顶点1为根的N个顶点,一个数组val []表示分配给每个顶点的值,以及一个数组cost []表示该中每个边的成本,任务是找到最小数量要从给定树中删除的叶子的数量,例如:

例子

方法:
请按照以下步骤解决问题:

  • 如果对于顶点V ,存在一个顶点U ,使得边成本(V –> U)超过val [U] ,则除了删除以UV为根的整个子树外,别无选择。仅允许删除叶顶点。
  • 由于只能删除叶顶点,因此要删除UV ,需要逐叶删除整个子树才能到达顶点UV。
  • 为了尽量减少被删除叶片数,贪婪地以较少数目顶点的选择的子树,如果以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)