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.
|
|
|
|
#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];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 功能:计算以u为起点,step步数下的权值
|
|
|
|
|
* @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;
|
|
|
|
|
}
|