给定一棵树,其中N个节点的值从1到N,且(N – 1)个Edge且值为K ,任务是从树中删除最少数量的节点,以便每个子树最多具有K个节点。移除节点会将边缘从该节点移除到所有其他连接的节点。
例子:
Input: N = 10, K = 3, Below is the graph:
Output:
Number of nodes removed: 2
Removed Nodes: 2 1
Explanation:
After removing the nodes 1 and 2, here, no subtree or tree has more than 3 nodes. Below is the resulting graph:
Input: N = 6, K = 3, Below is the graph:
Output:
Number of nodes removed: 1
Removed Nodes: 1
Explanation:
After removing the nodes 1, here, no subtree or tree has more than 3 nodes. Below is the resulting graph:
方法:我们的想法是,观察到在某个节点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)