【问题标题】:Find the sum of weights of edges between every pair of nodes in a weighted tree求加权树中每对节点之间的边权重之和
【发布时间】:2020-02-10 18:46:39
【问题描述】:

我需要找到一种有效的方法来找到加权树中所有简单路径的值之和。简单路径的值定义为给定简单路径中所有边的权重之和。

这是我的尝试,但它不起作用。请说出正确的做法。

#include <iostream>
#include <vector>

using namespace std;

typedef long long ll;
typedef pair<int, ll> pil;
const int MAXN = 1e5;
int n, color[MAXN + 2];
vector<pil> adj[MAXN + 2];
ll sum1, cnt1[MAXN + 2], cnt[MAXN + 2], res;

void visit(int u, int p)
{
    cnt[u] = 1;

    cnt1[u] = color[u];

    for (int i = 0; i < (int) adj[u].size(); ++i)
    {
        int v = adj[u][i].first;
        ll w = adj[u][i].second;

        if (v == p)
            continue;

        visit(v, u);
        ll tmp = cnt1[v] * (n - sum1 - cnt[v] + cnt1[v]);
        tmp += (cnt[v] - cnt1[v]) * (sum1 - cnt1[v]);
        res += tmp * w;

        cnt[u] += cnt[v];
        cnt1[u] += cnt1[v];
    }
}

int main()
{
    scanf("%d", &n);

    for (int i = 1; i <= n; ++i)
    {
        scanf("%d", color + i);
        sum1 += color[i];
    }

    for (int i = 1, u, v; i < n; ++i)
    {
        scanf("%d %d %lld", &u, &v, &res);
        adj[u].push_back(pil(v, res));
        adj[v].push_back(pil(u, res));
    }

    res = 0;

    visit(1, -1);
    printf("%lld\n", res);
    return 0;
}

【问题讨论】:

  • typedef long long ll; 翻译成英文是“在我向人们寻求帮助之前,让我们让我的代码更难阅读”。你会发现这并不是那么好用。
  • 这篇文章可能对geeksforgeeks.org/…有帮助

标签: c++ data-structures graph c++14 c++17


【解决方案1】:

下面是@Arjun Singh 解释的简单实现。

int64_t ans = 0;

int dfs(int node, int parent) {
    int cur_subtree_size = 1;
    for(int child : adj[node]) {
        if(parent != child) {
            int child_subtree_size = dfs(child, node);
            int64_t contribution_of_cur_edge = child_subtree_size * (N - child_subtree_size) * weight[{node, child}];
            ans += contribution_of_cur_edge;
            cur_subtree_size += child_subtree_size;
        }
    }
    return cur_subtree_size;
}

【讨论】:

    【解决方案2】:

    您可以计算每个边在最终答案中的贡献。假设一条边连接两个组件component1 ---- component2。那么这个边缘在最终答案中的贡献将是 - 顶点(组件1)*顶点(组件2)*边缘重量。

    没有。可以很容易地找到每个组件中的顶点数,运行 dfs 并计算每个顶点的子树中的顶点数。让一条边连接顶点 u 和 v。u 是 v 的父节点。那么, Vertices(v) = v 的子树中的顶点数 = Vertices(component1) 顶点(component2) = n - 顶点(v)

    您可以预先计算这个子树数组。所以最终的时间复杂度将是 O(n)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-25
      相关资源
      最近更新 更多