You are given an undirected connected graph of n nodes, numbered from 0 to n - 1. Each node is connected to at most 2 other nodes.
The graph consists of m edges, represented by a 2D array edges, where edges[i] = [ai, bi] indicates that there is an edge between nodes ai and bi.
You have to assign a unique value from 1 to n to each node. The value of an edge will be the product of the values assigned to the two nodes it connects.
Your score is the sum of the values of all edges in the graph.
Return the maximum score you can achieve.
Example 1:
Input: n = 4, edges = [[0,1],[1,2],[2,3]]
Output: 23
Explanation:
The diagram above illustrates an optimal assignment of values to nodes. The sum of the values of the edges is: (1 * 3) + (3 * 4) + (4 * 2) = 23.
Example 2:
Input: n = 6, edges = [[0,3],[4,5],[2,0],[1,3],[2,4],[1,5]]
Output: 82
Explanation:
The diagram above illustrates an optimal assignment of values to nodes. The sum of the values of the edges is: (1 * 2) + (2 * 4) + (4 * 6) + (6 * 5) + (5 * 3) + (3 * 1) = 82.
Constraints:
1 <= n <= 5 * 104m == edges.length1 <= m <= nedges[i].length == 20 <= ai, bi < nai != biWhen you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
To find the best possible total value for all the connections in a network, we need to assign a value to each point. The brute force method simply tries out every single possible combination of value assignments for all the points in the entire network.
Here's how the algorithm would work step-by-step:
def max_sum_brute_force(nodes_count, edges_list):
maximum_sum_found = 0
def find_max_sum_recursively(edge_index, current_selected_edges):
nonlocal maximum_sum_found
if edge_index == len(edges_list):
# This check is necessary to determine if the generated subset is 'legal' by the problem's rules.
is_valid_subset = True
nodes_in_subset = set()
for edge in current_selected_edges:
node_one, node_two, _ = edge
if node_one in nodes_in_subset or node_two in nodes_in_subset:
is_valid_subset = False
break
nodes_in_subset.add(node_one)
nodes_in_subset.add(node_two)
if is_valid_subset:
current_sum = sum(edge[2] for edge in current_selected_edges)
# We must update our maximum if this valid group's sum is greater than any found before.
maximum_sum_found = max(maximum_sum_found, current_sum)
return
# To generate every possible subset, we must explore the case where the current edge is included.
find_max_sum_recursively(edge_index + 1, current_selected_edges + [edges_list[edge_index]])
# And we must also explore the case where it is not included to cover all combinations.
find_max_sum_recursively(edge_index + 1, current_selected_edges)
find_max_sum_recursively(0, [])
return maximum_sum_foundInstead of checking every possible combination of connections, the ideal strategy solves the problem from the bottom up. By first calculating the best results for smaller sections of the graph, we can efficiently build up to the best solution for the entire structure.
Here's how the algorithm would work step-by-step:
def maximum_sum_of_edge_values(number_of_nodes, edges, values):
adjacency_list = [[] for _ in range(number_of_nodes)]
for first_node, second_node in edges:
adjacency_list[first_node].append(second_node)
adjacency_list[second_node].append(first_node)
def calculate_max_scores_for_subtree(current_node, parent_node):
sum_of_children_free_scores = 0
potential_gains_from_connection = []
for neighbor_node in adjacency_list[current_node]:
if neighbor_node == parent_node:
continue
child_score_if_taken, child_score_if_free = calculate_max_scores_for_subtree(neighbor_node, current_node)
sum_of_children_free_scores += child_score_if_free
current_edge_value = values[current_node] + values[neighbor_node]
# This calculates the net score change from connecting to a child versus leaving it free.
gain_from_this_connection = current_edge_value + child_score_if_taken - child_score_if_free
potential_gains_from_connection.append(gain_from_this_connection)
# If this node is 'taken' by its parent, it cannot form an edge with any of its own children.
max_score_if_taken_by_parent = sum_of_children_free_scores
max_gain_from_connecting_down = 0
if potential_gains_from_connection:
max_gain_from_connecting_down = max(potential_gains_from_connection)
# If 'free', this node can either not connect down, or form one edge with the most profitable child.
max_score_if_free_from_parent = sum_of_children_free_scores + max(0, max_gain_from_connecting_down)
return (max_score_if_taken_by_parent, max_score_if_free_from_parent)
# The root node has no parent, so its final score is its best possible 'free' state score.
_, final_total_score = calculate_max_scores_for_subtree(0, -1)
return final_total_score| Case | How to Handle |
|---|---|
| Large value of n causing the total score to overflow standard 32-bit integers. | The final sum must be stored in a 64-bit integer type (e.g., long long in C++, long in Java) to prevent overflow. |
| The graph is the smallest possible path, with n=2 nodes and one edge. | The path-finding logic correctly identifies the two endpoints and assigns the only possible values, 1 and 2. |
| The graph is the smallest possible cycle, a triangle with n=3 nodes. | The cycle-finding logic correctly traverses the loop and applies the optimal value assignment for a 3-node cycle. |
| The graph is a path with an odd number of nodes. | The value assignment strategy correctly handles the single central node in the path. |
| The graph is a cycle with an odd number of nodes. | The assignment logic correctly handles the unequal number of odd and even values that need to be arranged around the cycle. |
| Correctly identifying the graph structure as either a path or a cycle. | The solution must first analyze node degrees; a path will have two degree-1 nodes, while a cycle will have none. |
| Choosing the starting node for traversal in a path graph. | The traversal must start at one of the two unique degree-1 nodes to correctly sequence the nodes for value assignment. |
| Maximum-sized inputs requiring an efficient solution. | The solution must have a time complexity of O(n) or O(n+m) to pass within the time limit for n up to 5 * 10^4. |