📜  要删除的最小节点数,以使子树不超过K个节点

📅  最后修改于: 2021-04-22 03:28:57             🧑  作者: Mango

给定一棵树,其中N个节点的值从1N,(N – 1)个Edge且值为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)