给定n元树T ,任务是找到一个节点,该节点的删除将所生成的所有森林(连接的组件)的最大大小最小化。
例子:
Input:
1
/ | \
2 3 4
/ \
5 6
Output: 1
Explanation:
There are six nodes which can be removed to form forests:
Remove(1): Largest Forest size is 3
Remove(2): Largest Forest size is 3
Remove(3): Largest Forest size is 5
Remove(4): Largest Forest size is 5
Remove(5): Largest Forest size is 5
Remove(6): Largest Forest size is 5
Therefore, removing either node 1 or 2 minimizes the maximum forest size to 3.
Input:
1
/ \
2 3
Output: 1
Explanation:
There are three nodes which can be removed to form forests:
Remove(1): Largest Forest size is 1
Remove(2): Largest Forest size is 1
Remove(3): Largest Forest size is 1
Therefore, removing either node 1 or 2 or 3 minimizes the maximum forest size to 1.
方法:想法是使用“深度优先搜索遍历”遍历树,并对树的每个节点计算其子树中的节点数。从给定的树中删除任何节点都会导致两种不同类型的森林:
- 由子树(包括其左子元素和右子元素)形成的连接组件。
- 子树(包括其父节点)形成的连接组件
因此,请按照以下步骤解决问题:
- 使用DFS遍历树。
- 对于每个节点,递归计算其子树中的节点数。通过计算给定树中的节点总数与其子树中的节点总数之差,计算涉及其父项的连接组件中的节点数。
- 不断更新为任何节点获取的已连接组件的最大大小的最小值。
- 最后,打印与之对应的节点,以获取所连接组件最大大小的最小值。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
int mini = 105, ans, n;
vector > g(100);
int size[100];
// Function to create the graph
void create_graph()
{
g[1].push_back(2);
g[2].push_back(1);
g[1].push_back(3);
g[3].push_back(1);
g[1].push_back(4);
g[4].push_back(1);
g[2].push_back(5);
g[5].push_back(2);
g[2].push_back(6);
g[6].push_back(2);
}
// Function to traverse the graph
// and find the minimum of maximum
// size forest after removing a node
void dfs(int node, int parent)
{
size[node] = 1;
int mx = 0;
// Traversing every child subtree
// except the parent node
for (int y : g[node]) {
if (y == parent)
continue;
// Traverse all subtrees
dfs(y, node);
size[node] += size[y];
// Update the maximum
// size of forests
mx = max(mx, size[y]);
}
// Update the minimum of maximum
// size of forests obtained
mx = max(mx, n - size[node]);
// Condition to find the minimum
// of maximum size forest
if (mx < mini) {
mini = mx;
// Update and store the
// corresponding node
ans = node;
}
}
// Driver Code
int main()
{
n = 6;
create_graph();
dfs(1, -1);
cout << ans << "\n";
return 0;
}
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
static int mini = 105, ans, n;
static Vector []g = new Vector[100];
static int []size = new int[100];
// Function to create the graph
static void create_graph()
{
g[1].add(2);
g[2].add(1);
g[1].add(3);
g[3].add(1);
g[1].add(4);
g[4].add(1);
g[2].add(5);
g[5].add(2);
g[2].add(6);
g[6].add(2);
}
// Function to traverse the graph
// and find the minimum of maximum
// size forest after removing a node
static void dfs(int node, int parent)
{
size[node] = 1;
int mx = 0;
// Traversing every child subtree
// except the parent node
for (int y : g[node])
{
if (y == parent)
continue;
// Traverse all subtrees
dfs(y, node);
size[node] += size[y];
// Update the maximum
// size of forests
mx = Math.max(mx, size[y]);
}
// Update the minimum of maximum
// size of forests obtained
mx = Math.max(mx, n - size[node]);
// Condition to find the minimum
// of maximum size forest
if (mx < mini)
{
mini = mx;
// Update and store the
// corresponding node
ans = node;
}
}
// Driver Code
public static void main(String[] args)
{
n = 6;
for (int i = 0; i < g.length; i++)
g[i] = new Vector();
create_graph();
dfs(1, -1);
System.out.print(ans + "\n");
}
}
// This code is contributed by Princi Singh
Python3
# Python3 program to implement
# the above approach
mini = 105;
ans = 0;
n = 0;
g = [];
size = [0] * 100;
# Function to create the graph
def create_graph():
g[1].append(2);
g[2].append(1);
g[1].append(3);
g[3].append(1);
g[1].append(4);
g[4].append(1);
g[2].append(5);
g[5].append(2);
g[2].append(6);
g[6].append(2);
# Function to traverse the graph
# and find the minimum of maximum
# size forest after removing a Node
def dfs(Node, parent):
size[Node] = 1;
mx = 0;
global mini
global ans
# Traversing every child subtree
# except the parent Node
for y in g[Node]:
if (y == parent):
continue;
# Traverse all subtrees
dfs(y, Node);
size[Node] += size[y];
# Update the maximum
# size of forests
mx = max(mx, size[y]);
# Update the minimum of maximum
# size of forests obtained
mx = max(mx, n - size[Node]);
# Condition to find the minimum
# of maximum size forest
if (mx < mini):
mini = mx;
# Update and store the
# corresponding Node
ans = Node;
# Driver Code
if __name__ == '__main__':
n = 6;
for i in range(100):
g.append([])
create_graph();
dfs(1, -1);
print(ans);
# This code is contributed by 29AjayKumar
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
static int mini = 105, ans, n;
static List []g = new List[100];
static int []size = new int[100];
// Function to create the graph
static void create_graph()
{
g[1].Add(2);
g[2].Add(1);
g[1].Add(3);
g[3].Add(1);
g[1].Add(4);
g[4].Add(1);
g[2].Add(5);
g[5].Add(2);
g[2].Add(6);
g[6].Add(2);
}
// Function to traverse the graph
// and find the minimum of maximum
// size forest after removing a node
static void dfs(int node, int parent)
{
size[node] = 1;
int mx = 0;
// Traversing every child subtree
// except the parent node
foreach (int y in g[node])
{
if (y == parent)
continue;
// Traverse all subtrees
dfs(y, node);
size[node] += size[y];
// Update the maximum
// size of forests
mx = Math.Max(mx, size[y]);
}
// Update the minimum of maximum
// size of forests obtained
mx = Math.Max(mx, n - size[node]);
// Condition to find the minimum
// of maximum size forest
if (mx < mini)
{
mini = mx;
// Update and store the
// corresponding node
ans = node;
}
}
// Driver Code
public static void Main(String[] args)
{
n = 6;
for (int i = 0; i < g.Length; i++)
g[i] = new List();
create_graph();
dfs(1, -1);
Console.Write(ans + "\n");
}
}
// This code is contributed by gauravrajput1
2
时间复杂度: O(N),其中N是节点数。
辅助空间: O(N)