c++ - 求加权树中每对节点之间的边权重之和
问题描述
我需要找到一种有效的方法来找到加权树中所有简单路径的值之和。简单路径的值定义为给定简单路径中所有边的权重之和。
这是我的尝试,但它不起作用。请告诉正确的做法。
#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;
}
解决方案
以下是@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;
}
推荐阅读
- reactjs - TypeScript 与 Luxon 的兼容性
- apache-spark - 无法在 PySpark 中按多行获得平均值和标准差
- python - 隐藏的输入字段未显示从 Django 中的 views.py 访问的正确值
- python - 在工厂函数和动态继承之外定义类
- ios - Apple 是否支持使用 .net mvc5 或 webapi2 进行外部登录
- html - 如何从两端缩短底部边框?
- pythonanywhere - 在 pythonanywhere 中部署 django 应用程序时出错
- python - 赋值前引用的 Tkinter 变量“Num1”
- python-3.x - 如何使用 pandas 以 csv 格式将每个数组存储在不同的列中?
- php - WordPress如何在我的自定义页面中显示function.php文件中的变量值?