You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
2.3 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 210;
bool st[N]; //是不是走过了
int n, ans = 0x3f3f3f3f;
struct Node {
int sq_sum; //几号结点
int left; //左儿子
int right; //右儿子
int value; //此结点的人数
int parent; //父亲是哪结点
} nodes[N];
/**
* ustep
* @param u
* @param step
* @return
*/
int dfs(int u, int step) {
//不加st数组的话会Memory Limit Exceed 超出内存限制
//如果不加st数组的话就会发生它调了它的父亲它的父亲又调了它来来回回不死不休~,这样看来,状态数组是多么的重要啊~
//问题1什么时间退出递归nodes[u].num==0表示找到了一个终端结点就是叶子
if (nodes[u].num == 0 || st[u] == true) return 0;
//标识为已使用过
st[u] = true;
//问题2如何计算整体的权值
//这里就是个深度优先搜索,三个侦察兵,左子树,右子树,父子树的距离和.
//分别对三个方向的侦查兵说以你为根的子树距离我step+1这么远你负责统计一下你子树的距离和
//[u,step]的权值=dfs(左儿子)+dfs(右儿子)+自己的权值+dfs(父亲)
return dfs(nodes[u].left, step + 1) + dfs(nodes[u].right, step + 1) +
dfs(nodes[u].parent, step + 1) + nodes[u].value * step;
}
int main() {
//读入数据
cin >> n;
for (int i = 1; i <= n; i++) {
//读入权值,左儿子,右儿子
cin >> nodes[i].value >> nodes[i].left >> nodes[i].right;
//记录结点号
nodes[i].num = i;
//记录左右儿子的父亲节点
nodes[nodes[i].left].parent = i; //为了找到父亲
nodes[nodes[i].right].parent = i;//为了找到父亲
}
//遍历每个结点作为医院部署地
for (int i = 1; i <= n; i++) {
//每次出发前,注意要清空状态数组,防止状态记录错误
memset(st, 0, sizeof st);
//每个结点作为医院部署地,都会产生一个距离和,取最小值
ans = min(ans, dfs(i, 0));
}
cout << ans << endl;
return 0;
}