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.
This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.
# 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 ;
}