'commit'
This commit is contained in:
59
TangDou/LuoGuBook/P1364_binaryTree_Dfs.cpp
Normal file
59
TangDou/LuoGuBook/P1364_binaryTree_Dfs.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user