一个节点到每个其他节点的最大距离总和
给定一棵无向连通树,其N个节点的值从0到N – 1 ,数组edges[][2]表示两个节点之间的边,任务是找到一个节点到其他节点的最大距离总和那个树。
例子:
Input: N = 5, edges = { {0, 2}, {1, 3}, {0, 1}, {3, 4} }
Output: 10
Explanation:
Considering the node 2 as the sources node, the distances of all other nodes from node 2 are: 1(node 0), 2(node 1), 3(node 3), 4(node 4). Therefore, the sum of distances is 1 + 2 + 3 + 4 = 10.
Input: N = 6, edges[][] = {{0, 1}, {0, 2}, {2, 3}, {2, 4}, {2, 5}}
Output: 12
朴素方法:解决给定问题的最简单方法是从每个节点执行深度优先搜索遍历,并找到每个其他节点与当前源节点的距离之和。从作为源节点的所有节点检查后,打印获得的所有值的总和中的最大总和。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to perform DFS and find the
// distance from a node to every other
// node
void dfs(int s, vector > g,
int p, int d, int& ans)
{
for (int i : g[s]) {
// If i is not equal to
// parent p
if (i != p) {
ans += d;
dfs(i, g, s, d + 1, ans);
}
}
}
// Function to find the maximum sum of
// distance from a node to every other
// node
void maxPotentialDistance(
int N, vector >& edges)
{
int ans = 0;
// Construct the graph
vector > g(N, vector());
for (auto& it : edges) {
g[it[0]].push_back(it[1]);
g[it[1]].push_back(it[0]);
}
// Find the sum of distances from
// every node
for (int i = 0; i < N; i++) {
// Stores the maximum sum of
// distance considering the
// current node as source node
int a = 0;
// Perform DFS Traversal to
// find the sum of distances
dfs(i, g, -1, 1, a);
// Update the maximum sum
ans = max(ans, a);
}
// Print the maximum sum
cout << ans;
}
// Driver Code
int main()
{
int N = 6;
vector > edges = {
{ 0, 1 }, { 0, 2 }, { 2, 3 }, { 2, 4 }, { 2, 5 }
};
maxPotentialDistance(N, edges);
return 0;
}
Python3
# python program for the above approach
pd_0 = 0
# Function to perform DFS and find the
# distance from a node to every other
# node
def dfs(s, g, p, d, count):
global pd_0
for i in g[s]:
# If i is not equal to
# parent p
if (i != p):
pd_0 += d
# Perform the DFS Traversal
dfs(i, g, s, d + 1, count)
# Update the count of
# nodes
count[s] = count[s] + count[i]
# Function to find the distances from
# every other node using distance from
# node 0
def dfs2(s, g, p, pd_all, n, count):
for i in g[s]:
# If i is not equal to the
# parent p
if (i != p):
pd_all[i] = pd_all[s] - count[i] + n - count[i]
dfs2(i, g, s, pd_all, n, count)
# Function to find the maximum sum of
# distance from a node to every other
# node
def maxPotentialDistance(N, edges):
global pd_0
ans = 0
# Construct the graph
g = [[] for _ in range(N)]
for it in edges:
g[it[0]].append(it[1])
g[it[1]].append(it[0])
# Stores the number of nodes in
# each subtree
count = [1 for _ in range(N)]
# Find the sum of distances from
# node 0 and count the number of
# nodes in each subtree
dfs(0, g, -1, 1, count)
# Stores distances from each node
pd_all = [0 for _ in range(N)]
pd_all[0] = pd_0
# Find the distances from each
# node using distance from node 0
dfs2(0, g, -1, pd_all, N, count)
# Find the result
for i in pd_all:
ans = max(ans, i)
# Print the result
print(ans)
# Driver Code
if __name__ == "__main__":
N = 6
edges = [
[0, 1], [0, 2], [2, 3], [2, 4], [2, 5]
]
maxPotentialDistance(N, edges)
# This code is contributed by rakeshsahni
C++
// C++ program for the above approach
#include
using namespace std;
// Function to perform DFS and find the
// distance from a node to every other
// node
void dfs(int s, vector > g,
int p, int d, int& ans,
vector& count)
{
for (int i : g[s]) {
// If i is not equal to
// parent p
if (i != p) {
ans += d;
// Perform the DFS Traversal
dfs(i, g, s, d + 1,
ans, count);
// Update the count of
// nodes
count[s] = count[s] + count[i];
}
}
}
// Function to find the distances from
// every other node using distance from
// node 0
void dfs2(int s, vector > g,
int p, vector& pd_all,
int n, vector count)
{
for (int i : g[s]) {
// If i is not equal to the
// parent p
if (i != p) {
pd_all[i] = pd_all[s]
- count[i]
+ n - count[i];
dfs2(i, g, s, pd_all,
n, count);
}
}
}
// Function to find the maximum sum of
// distance from a node to every other
// node
void maxPotentialDistance(
int N, vector >& edges)
{
int ans = 0;
// Construct the graph
vector > g(N, vector());
for (auto& it : edges) {
g[it[0]].push_back(it[1]);
g[it[1]].push_back(it[0]);
}
// Stores the number of nodes in
// each subtree
vector count(N, 1);
int pd_0 = 0;
// Find the sum of distances from
// node 0 and count the number of
// nodes in each subtree
dfs(0, g, -1, 1, pd_0, count);
// Stores distances from each node
vector pd_all(N, 0);
pd_all[0] = pd_0;
// Find the distances from each
// node using distance from node 0
dfs2(0, g, -1, pd_all, N, count);
// Find the result
for (int i : pd_all)
ans = max(ans, i);
// Print the result
cout << ans;
}
// Driver Code
int main()
{
int N = 6;
vector > edges = {
{ 0, 1 }, { 0, 2 }, { 2, 3 }, { 2, 4 }, { 2, 5 }
};
maxPotentialDistance(N, edges);
return 0;
}
12
时间复杂度: O(N 2 )
辅助空间: O(N)
有效方法:上述方法也可以通过观察节点到每个其他节点的距离总和之间的关系来优化。让我们以节点x 为例。如果y是它的孩子,那么可以观察到y和x的距离之和是相关的;
distance of y = distance x – number of nodes in subtree y + nodes that are not in the subtree y
所有节点的所需距离可以通过计算到一个节点的距离之和并知道每个子树中的节点数来计算。请按照以下步骤解决问题:
- 定义一个函数dfs(int s, vector
> graph, int p, int d, int &ans, vector 并执行以下步骤:& count) - 使用变量i在范围[0, graph[s]]上进行迭代,如果i不等于p,则将ans的值增加d并调用函数dfs(i, graph, s, d + 1, ans , count)探索其他节点并将count[s]的值设置为(count[s] + count[i]) 。
- 定义一个函数dfs2(int s, vector
> graph, int p, vector 并执行以下步骤:&pd_all, int N, vector & count) - 使用变量i在范围[0, graph[s]]上进行迭代,如果i不等于p,则将pd_all[i]的值设置为(pd_all[s] – count[i] + n – count[ i])并调用函数dfs(i, graph, s, pd_all, N, count)来查找其他节点的答案。
- 初始化变量,比如存储结果的ans 。
- 从给定的边[][]构造一个邻接表, graph[ ]。
- 初始化大小为N的向量count[]以跟踪给定节点的子树中的节点计数。
- 将变量pd_0初始化为0以存储从节点0到树中每个其他节点的距离总和。
- 调用函数dfs(s, graph, p, d, ans, count)以找到从节点0到每个其他节点所需的距离,并将节点数存储在子树中。
- 初始化大小为N的向量pd_all[]以存储与其他每个节点的距离。
- 将pd_all[0]的值设置为pd_0 。
- 调用函数dfs2(s, graph, p, pd_all, N, count)以找到与其他每个节点的所需距离。
- 使用变量i迭代范围[0, N]并将ans的值更新为ans或pd_all[i]的最大值。
- 执行上述步骤后,打印ans的值作为答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to perform DFS and find the
// distance from a node to every other
// node
void dfs(int s, vector > g,
int p, int d, int& ans,
vector& count)
{
for (int i : g[s]) {
// If i is not equal to
// parent p
if (i != p) {
ans += d;
// Perform the DFS Traversal
dfs(i, g, s, d + 1,
ans, count);
// Update the count of
// nodes
count[s] = count[s] + count[i];
}
}
}
// Function to find the distances from
// every other node using distance from
// node 0
void dfs2(int s, vector > g,
int p, vector& pd_all,
int n, vector count)
{
for (int i : g[s]) {
// If i is not equal to the
// parent p
if (i != p) {
pd_all[i] = pd_all[s]
- count[i]
+ n - count[i];
dfs2(i, g, s, pd_all,
n, count);
}
}
}
// Function to find the maximum sum of
// distance from a node to every other
// node
void maxPotentialDistance(
int N, vector >& edges)
{
int ans = 0;
// Construct the graph
vector > g(N, vector());
for (auto& it : edges) {
g[it[0]].push_back(it[1]);
g[it[1]].push_back(it[0]);
}
// Stores the number of nodes in
// each subtree
vector count(N, 1);
int pd_0 = 0;
// Find the sum of distances from
// node 0 and count the number of
// nodes in each subtree
dfs(0, g, -1, 1, pd_0, count);
// Stores distances from each node
vector pd_all(N, 0);
pd_all[0] = pd_0;
// Find the distances from each
// node using distance from node 0
dfs2(0, g, -1, pd_all, N, count);
// Find the result
for (int i : pd_all)
ans = max(ans, i);
// Print the result
cout << ans;
}
// Driver Code
int main()
{
int N = 6;
vector > edges = {
{ 0, 1 }, { 0, 2 }, { 2, 3 }, { 2, 4 }, { 2, 5 }
};
maxPotentialDistance(N, edges);
return 0;
}
12
时间复杂度: O(N)
辅助空间: O(N)