📜  要删除的最小节点数,这样子树的节点数不会超过 K 个

📅  最后修改于: 2021-09-04 08:06:59             🧑  作者: Mango

给定一棵树,它有N 个节点值从1N(N – 1) 条边和一个数字K ,任务是从树中删除最少数量的节点,使得每个子树最多有K 个节点。删除节点将删除从该节点到所有其他连接节点的边。

例子:

方法:思想是观察一个节点X的子树中的节点数是其子节点的子树中的节点数与该节点本身的总和。以下是步骤:

  • 用动态规划和DFS存储节点的计数,在每个节点的子树容易。
  • 现在,为了没有节点的子树超过 K 个节点,想法是在其子树中的节点超过 K 个时删除该节点,并将 0 传递给其父节点。
  • 在上面的步骤中,我们让每个节点在其子树中的节点不大于 K 并最小化节点删除的数量。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
#define N 20
 
// Function to perform DFS Traversal
int dfs(vector &visited, int s,
        int &K, int &removals,
        vector &removed_nodes,
        vector> &adj)
{
   
  // Mark the node as true
  visited[s] = true;
  int nodes = 1;
 
  // Traverse adjacency list
  // of child node
  for(int child : adj[s])
  {
     
    // If already visited then
    // omit the node
    if (visited[child])
      continue;
 
    // Add number of nodes
    // in subtree
    nodes += dfs(visited, child, K,
                 removals, removed_nodes,
                 adj);
  }
 
  if (nodes > K)
  {
     
    // Increment the count
    removals++;
    removed_nodes.push_back(s);
    nodes = 0;
  }
 
  // Return the nodes
  return nodes;
}
 
// Function to add edges in graph
void addEdge(vector> &adj,
             int a, int b)
{
  adj[a].push_back(b);
  adj[b].push_back(a);
}
 
// Function that finds the number
// of nodes to be removed such that
// every subtree has size at most K
void findRemovedNodes(vector &visited, int K,
                      int &removals,
                      vector &removed_nodes,
                      vector> &adj)
{
   
  // Function Call to find the
  // number of nodes to remove
  dfs(visited, 1, K, removals,
      removed_nodes, adj);
 
  // Print Removed Nodes
  cout << "Number of nodes removed: "
       << removals << endl;
 
  cout << "Removed Nodes: ";
  for(int node : removed_nodes)
  {
    cout << node << " ";
  }
}
 
// Driver Code
int main()
{
   
  // Variables used to store data globally
  vector visited(N);
  int K;
  int removals = 0;
  vector removed_nodes;
 
  // Adjacency list representation of tree
  vector> adj(N);
 
  // Insert of nodes in graph
  addEdge(adj, 1, 2);
  addEdge(adj, 1, 3);
  addEdge(adj, 2, 4);
  addEdge(adj, 2, 5);
  addEdge(adj, 3, 6);
 
  // Required subtree size
  K = 3;
   
  // Function Call
  findRemovedNodes(visited, K, removals,
                   removed_nodes, adj);
 
  return 0;
}
 
// This code is contributed by sanjeev2552


Java
// Java program for the above approach
import java.util.*;
 
class GFG {
 
    // Variables used to store data globally
    static final int N = 20;
    static boolean visited[] = new boolean[N];
    static int K;
    static int removals = 0;
    static ArrayList removed_nodes
        = new ArrayList<>();
 
    // Adjacency list representation of tree
    static ArrayList > adj
        = new ArrayList<>();
 
    // Function to perform DFS Traversal
    static int dfs(int s)
    {
        // Mark the node as true
        visited[s] = true;
        int nodes = 1;
 
        // Traverse adjacency list
        // of child node
        for (Integer child : adj.get(s)) {
 
            // If already visited then
            // omit the node
            if (visited[child])
                continue;
 
            // Add number of nodes
            // in subtree
            nodes += dfs(child);
        }
 
        if (nodes > K) {
 
            // Increment the count
            removals++;
            removed_nodes.add(s);
            nodes = 0;
        }
 
        // Return the nodes
        return nodes;
    }
 
    // Function to add edges in graph
    static void addEdge(int a, int b)
    {
        adj.get(a).add(b);
        adj.get(b).add(a);
    }
 
    // Function that finds the number
    // of nodes to be removed such that
    // every subtree has size at most K
    public static void findRemovedNodes(int K)
    {
        // Function Call to find the
        // number of nodes to remove
        dfs(1);
 
        // Print Removed Nodes
        System.out.println("Number of nodes"
                           + " removed: "
                           + removals);
 
        System.out.print("Removed Nodes: ");
        for (int node : removed_nodes)
            System.out.print(node + " ");
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Creating list for all nodes
        for (int i = 0; i < N; i++)
            adj.add(new ArrayList<>());
 
        // Insert of nodes in graph
        addEdge(1, 2);
        addEdge(1, 3);
        addEdge(2, 4);
        addEdge(2, 5);
        addEdge(3, 6);
 
        // Required subtree size
        K = 3;
 
        // Function Call
        findRemovedNodes(K);
    }
}


Python3
# Python3 program for the above approach
 
# Variables used to store data globally
N = 20
visited = [False for i in range(N)]
K = 0
removals = 0
removed_nodes = []
 
# Adjacency list representation of tree
adj = [[] for i in range(N)]
 
# Function to perform DFS Traversal
def dfs(s):
     
    global removals
     
    # Mark the node as true
    visited[s] = True
    nodes = 1
 
    # Traverse adjacency list
    # of child node
    for child in adj[s]:
 
        # If already visited then
        # omit the node
        if (visited[child]):
            continue
 
        # Add number of nodes
        # in subtree
        nodes += dfs(child)
 
    if (nodes > K):
 
        # Increment the count
        removals += 1
        removed_nodes.append(s)
        nodes = 0
 
    # Return the nodes
    return nodes
 
# Function to add edges in graph
def addEdge(a, b):
 
    adj[a].append(b)
    adj[b].append(a)
 
# Function that finds the number
# of nodes to be removed such that
# every subtree has size at most K
def findRemovedNodes(K):
 
    # Function Call to find the
    # number of nodes to remove
    dfs(1)
 
    # Print Removed Nodes
    print("Number of nodes removed: ", removals)
 
    print("Removed Nodes: ", end = ' ')
     
    for node in removed_nodes:
        print(node, end = ' ')
     
# Driver Code
if __name__ == "__main__":
 
    # Insert of nodes in graph
    addEdge(1, 2)
    addEdge(1, 3)
    addEdge(2, 4)
    addEdge(2, 5)
    addEdge(3, 6)
 
    # Required subtree size
    K = 3
 
    # Function Call
    findRemovedNodes(K)
 
# This code is contributed by rutvik_56


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
  // Variables used to store data globally
  static readonly int N = 20;
  static bool []visited = new bool[N];
  static int K;
  static int removals = 0;
  static List removed_nodes
    = new List();
 
  // Adjacency list representation of tree
  static List > adj
    = new List>();
 
  // Function to perform DFS Traversal
  static int dfs(int s)
  {
    // Mark the node as true
    visited[s] = true;
    int nodes = 1;
 
    // Traverse adjacency list
    // of child node
    foreach (int child in adj[s])
    {
 
      // If already visited then
      // omit the node
      if (visited[child])
        continue;
 
      // Add number of nodes
      // in subtree
      nodes += dfs(child);
    }
 
    if (nodes > K)
    {
 
      // Increment the count
      removals++;
      removed_nodes.Add(s);
      nodes = 0;
    }
 
    // Return the nodes
    return nodes;
  }
 
  // Function to add edges in graph
  static void addEdge(int a, int b)
  {
    adj[a].Add(b);
    adj[b].Add(a);
  }
 
  // Function that finds the number
  // of nodes to be removed such that
  // every subtree has size at most K
  public static void findRemovedNodes(int K)
  {
    // Function Call to find the
    // number of nodes to remove
    dfs(1);
 
    // Print Removed Nodes
    Console.WriteLine("Number of nodes" +    
                           " removed: " +
                               removals);
 
    Console.Write("Removed Nodes: ");
    foreach (int node in removed_nodes)
      Console.Write(node + " ");
  }
 
  // Driver Code
  public static void Main(String[] args)
  {
    // Creating list for all nodes
    for (int i = 0; i < N; i++)
      adj.Add(new List());
 
    // Insert of nodes in graph
    addEdge(1, 2);
    addEdge(1, 3);
    addEdge(2, 4);
    addEdge(2, 5);
    addEdge(3, 6);
 
    // Required subtree size
    K = 3;
 
    // Function Call
    findRemovedNodes(K);
  }
}
 
// This code is contributed by Rohit_ranjan


输出
Number of nodes removed: 1
Removed Nodes: 1

时间复杂度: O(N)
辅助空间: O(N)

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live