- 将所有边看成无向边
- 枚举每一个点作为root的时候这棵树的权重
- 求第二步 中的最小res
下面是dfs 和 bfs的实现
dfs:
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
class Solve {
public:
Solve(int _n) : n(_n), g(n + 1), vertexToWegeight(n + 1)
{
for (int i = 1; i <= n; ++i) {
int a, b, w;
cin >> w >> a >> b;
vertexToWegeight[i] = w;
if (a) g[i].push_back(a), g[a].push_back(i);
if (b) g[i].push_back(b), g[b].push_back(i);
}
}
void operator()()
{
int res = 0x3f3f3f3f;
for (int i = 1; i <= n; ++i) {
res = min(res, dfs(i, -1, 0));
}
cout << res << endl;
}
private:
// 返回以 root为根结点,father为父节点的树
// 的权重之和
int dfs(int root, int father, int k)
{
int res = vertexToWegeight[root] * k; // 加上这个结点的值
for (const auto v : g[root])
if (v != father) // 不能往回走
res += dfs(v, root, k + 1); // 加上儿子结点的路径
return res;
}
private:
int n;
vector<int> vertexToWegeight;
vector<vector<int>> g;
};
int main()
{
ios::sync_with_stdio(false);
int n;
cin >> n;
Solve{n}();
return 0;
}
bfs
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
class Solve {
public:
Solve(int _n) : n(_n), g(n + 1), vertexToWegeight(n + 1)
{
for (int i = 1; i <= n; ++i) {
int a, b, w;
cin >> w >> a >> b;
vertexToWegeight[i] = w;
if (a) g[i].push_back(a), g[a].push_back(i);
if (b) g[i].push_back(b), g[b].push_back(i);
}
}
void operator()()
{
int res = 0x3f3f3f3f;
for (int i = 1; i <= n; ++i) {
vector<int> q{i};
vector<int> st(n + 1);
st[i] = true;
int w = 1; // 每一层的权重
int sub = 0; // 这颗树 的权重和
while (!q.empty()) {
vector<int> tmp;
for (const auto qi : q) {
for (const auto v : g[qi]) { // 邻接点
if (!st[v]) {
tmp.push_back(v);
sub += vertexToWegeight[v] * w;
st[v] = true;
}
}
}
++w;
q = move(tmp);
}
// cout << sub << "sub " << endl;
res = min(sub, res);
}
cout << res << endl;
}
private:
int n;
vector<int> vertexToWegeight;
vector<vector<int>> g;
};
int main()
{
ios::sync_with_stdio(false);
int n;
cin >> n;
Solve{n}();
return 0;
}
捉~
嘻嘻~