📌  相关文章
📜  一个节点到每个其他节点的最大距离总和

📅  最后修改于: 2022-05-13 01:56:04.255000             🧑  作者: Mango

一个节点到每个其他节点的最大距离总和

给定一棵无向连通树,其N个节点的值从0N – 1 ,数组edges[][2]表示两个节点之间的边,任务是找到一个节点到其他节点的最大距离总和那个树。

例子:

朴素方法:解决给定问题的最简单方法是从每个节点执行深度优先搜索遍历,并找到每个其他节点与当前源节点的距离之和。从作为源节点的所有节点检查后,打印获得的所有值的总和中的最大总和。

下面是上述方法的实现:

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是它的孩子,那么可以观察到yx的距离之和是相关的;

所有节点的所需距离可以通过计算到一个节点的距离之和并知道每个子树中的节点数来计算。请按照以下步骤解决问题:

  • 定义一个函数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的值更新为anspd_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)