给定一个由N个节点组成的N数组树,该树的根节点为1 ,边缘为{u,v}形式,并且数组values []由N个整数组成。每个顶点i都有一个由values [i]表示的整数值。任务是通过将其值添加到其子顶点的非空子集中,找到每个顶点i可能的最大子树总和。
例子:
Input: Edges[][] = {{1, 2}, {1, 3}, {3, 4}}, values[] = {1, -1, 0, 1}
Output: 2 -1 1 1
Explanation:
Below is the given Tree:
1
/ \
2 3
\
4
Following subsets can be chosen for each vertex:
Vertex 1: Subset of vertices {1, 3, 4} can be chosen with values {1, 0, 1}. Therefore, sum = 1 + 0 + 1 = 2.
Vertex 2: Subset of vertices {2} can be chosen with values {-1}. Therefore, sum = -1.
Vertex 3: Subset of vertices {3, 4} can be chosen with values {0, 1}. Therefore, sum = 0 + 1 = 1.
Vertex 4: Subset of vertices {4} can be chosen with values {1}. Therefore, sum = 1.
Input: Edges[][] = {{1, 2}, {1, 3}, {2, 4}, {2, 5}}, values[] = {1, -1, -2, 1, 3}
Output: 5 4 -2 1 3
Explanation:
Below is the given Tree:
1
/ \
2 3
/ \
4 5
Following subsets can be chosen for each vertex:
Vertex 1: Subset of vertices {1, 4, 5} can be chosen with values {1, 1, 3}. Therefore, sum = 1 + 1 + 3 = 5.
Vertex 2: Subset of vertices {4, 5} can be chosen with values {1, 3}. Therefore, sum = 1 + 3 = 4.
Vertex 3: Subset of vertices {3} can be chosen with values {-2}. Therefore, sum = -2.
Vertex 4: Subset of vertices {4} can be chosen with values {1}. Therefore, sum = 1.
Vertex 5: Subset of vertices {5} can be chosen with values {3}. Therefore, sum = 3.
天真的方法:最简单的方法是从1到N遍历每个顶点i的子树,并对其执行DFS遍历。对于每个顶点i ,选择其子顶点具有非负值的子集。如果所选顶点的子集为空,则搜索并打印具有最小值的节点,使其成为顶点i的子节点。否则,打印子集中存在的节点的节点值之和。
时间复杂度: O(N 2 )
辅助空间: O(N)
高效方法:想法是使用DFS遍历和动态编程方法。请按照以下步骤解决问题:
- 初始化大小为N的数组ans [] ,以存储每个顶点的最大子树总和。
- 对每个顶点执行DFS遍历,并为每个顶点初始化v , ans [v] ,并使其具有较大的负值。
- 如果顶点v是叶顶点,则该顶点的答案将是values [v] 。因此,分配ans [v] = values [v] 。
- 否则,遍历与顶点v相邻的顶点,并为每个相邻的顶点u ,将ans [v]更新为ans [v] = max(ans [u] + values [v],values [v],ans [u]) 。
- 完成上述步骤后,打印存储在ans []数组中的值作为每个顶点的答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
#define V 3
#define M 2
// Function to perform the DFS
// Traversal on the given Tree
void dfs(int v, int p,
vector adj[],
int ans[], int vals[])
{
// To check if v is leaf vertex
bool isLeaf = 1;
// Initialize answer for vertex v
ans[v] = INT_MIN;
// Traverse adjacency list of v
for(int u : adj[v])
{
if (u == p)
continue;
isLeaf = 0;
dfs(u, v, adj, ans, vals);
// Update maximum subtree sum
ans[v] = max(ans[u] + vals[v],
max(ans[u], vals[u]));
}
// If v is leaf
if (isLeaf)
{
ans[v] = vals[v];
}
}
// Function to calculate maximum
// subtree sum for each vertex
void printAnswer(int n,
int edges[V][M],
int values[])
{
// Stores the adjacency list
vector adj[n];
// Add Edegs to the list
for(int i = 0; i < n - 1; i++)
{
int u = edges[i][0] - 1;
int v = edges[i][1] - 1;
adj[u].push_back(v);
adj[v].push_back(u);
}
// Stores largest subtree
// sum for each vertex
int ans[n] ;
// Calculate answer
dfs(0, -1, adj, ans, values);
// Print the result
for(auto x : ans)
{
cout << x << " ";
}
}
// Driver Code
int main()
{
// Given nodes
int N = 4;
// Give N edges
int edges[V][M] = { { 1, 2 },
{ 1, 3 },
{ 3, 4 } };
// Given values
int values[] = { 1, -1, 0, 1 };
// Function Call
printAnswer(N, edges, values);
}
// This code is contributed by Princi Singh
Java
// Java program for the above approach
import java.io.*;
import java.util.ArrayList;
@SuppressWarnings("unchecked")
class GFG {
// Function to perform the DFS
// Traversal on the given Tree
static void dfs(int v, int p,
ArrayList adj[],
int ans[], int vals[])
{
// To check if v is leaf vertex
boolean isLeaf = true;
// Initialize answer for vertex v
ans[v] = Integer.MIN_VALUE;
// Traverse adjacency list of v
for (int u : adj[v]) {
if (u == p)
continue;
isLeaf = false;
dfs(u, v, adj, ans, vals);
// Update maximum subtree sum
ans[v] = Math.max(
ans[u] + vals[v],
Math.max(ans[u],
vals[u]));
}
// If v is leaf
if (isLeaf) {
ans[v] = vals[v];
}
}
// Function to calculate maximum
// subtree sum for each vertex
static void printAnswer(
int n, int edges[][], int values[])
{
// Stores the adjacency list
ArrayList adj[]
= new ArrayList[n];
for (int i = 0; i < n; i++)
adj[i] = new ArrayList<>();
// Add Edegs to the list
for (int i = 0; i < n - 1; i++) {
int u = edges[i][0] - 1;
int v = edges[i][1] - 1;
adj[u].add(v);
adj[v].add(u);
}
// Stores largest subtree
// sum for each vertex
int ans[] = new int[n];
// Calculate answer
dfs(0, -1, adj, ans, values);
// Print the result
for (int x : ans) {
System.out.print(x + " ");
}
}
// Driver Code
public static void main(String[] args)
{
// Given nodes
int N = 4;
// Give N edges
int edges[][]
= new int[][] { { 1, 2 },
{ 1, 3 },
{ 3, 4 } };
// Given values
int values[] = { 1, -1, 0, 1 };
// Function Call
printAnswer(N, edges, values);
}
}
C#
// C# program for the
// above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to perform the DFS
// Traversal on the given Tree
static void dfs(int v, int p,
List []adj,
int []ans, int []vals)
{
// To check if v is leaf
// vertex
bool isLeaf = true;
// Initialize answer for
// vertex v
ans[v] = int.MinValue;
// Traverse adjacency list
// of v
foreach (int u in adj[v])
{
if (u == p)
continue;
isLeaf = false;
dfs(u, v, adj, ans, vals);
// Update maximum subtree
// sum
ans[v] = Math.Max(ans[u] +
vals[v],
Math.Max(ans[u],
vals[u]));
}
// If v is leaf
if (isLeaf)
{
ans[v] = vals[v];
}
}
// Function to calculate maximum
// subtree sum for each vertex
static void printAnswer(int n,
int [,]edges,
int []values)
{
// Stores the adjacency list
List []adj =
new List[n];
for (int i = 0; i < n; i++)
adj[i] = new List();
// Add Edegs to the list
for (int i = 0;
i < n - 1; i++)
{
int u = edges[i, 0] - 1;
int v = edges[i, 1] - 1;
adj[u].Add(v);
adj[v].Add(u);
}
// Stores largest subtree
// sum for each vertex
int []ans = new int[n];
// Calculate answer
dfs(0, -1, adj,
ans, values);
// Print the result
foreach (int x in ans)
{
Console.Write(x + " ");
}
}
// Driver Code
public static void Main(String[] args)
{
// Given nodes
int N = 4;
// Give N edges
int [,]edges = new int[,] {{1, 2},
{1, 3},
{3, 4}};
// Given values
int []values = {1, -1, 0, 1};
// Function Call
printAnswer(N, edges, values);
}
}
// This code is contributed by gauravrajput1
Python3
# Python3 program for the above approach
V = 3
M = 2
# Function to perform the DFS
# Traversal on the given Tree
def dfs(v, p):
# To check if v is leaf vertex
isLeaf = 1
# Initialize answer for vertex v
ans[v] = -10**9
# Traverse adjacency list of v
for u in adj[v]:
if (u == p):
continue
isLeaf = 0
dfs(u, v)
# Update maximum subtree sum
ans[v] = max(ans[u] + vals[v],max(ans[u], vals[u]))
# If v is leaf
if (isLeaf):
ans[v] = vals[v]
# Function to calculate maximum
# subtree sum for each vertex
def printAnswer(n, edges, vals):
# Stores the adjacency list
# vector adj[n];
# Add Edegs to the list
for i in range(n - 1):
u = edges[i][0] - 1
v = edges[i][1] - 1
adj[u].append(v)
adj[v].append(u)
# Calculate answer
dfs(0, -1)
# Prthe result
for x in ans:
print(x, end=" ")
# Driver Code
if __name__ == '__main__':
# Given nodes
N = 4
# Give N edges
edges=[ [ 1, 2],
[ 1, 3],
[ 3, 4] ]
adj=[[] for i in range(N)]
ans=[0 for i in range(N)]
# Given values
vals=[1, -1, 0, 1]
# Function Call
printAnswer(N, edges, vals)
# This code is contributed by mohit kumar 29
2 -1 1 1
时间复杂度: O(N)
辅助空间: O(N)