1338:【例3-3】医院设置
【题目描述】
设有一棵二叉树(如下图),其中圈中的数字表示结点中居民的人口,圈边上数字表示结点编号。现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻结点之间的距离为11。就本图而言,若医院建在11处,则距离和=4+12+2×20+2×40=136=4+12+2×20+2×40=136;若医院建在33处,则距离和=4×2+13+20+40=81=4×2+13+20+40=81……
【输入】
第一行一个整数nn,表示树的结点数(n≤100n≤100)。接下来的nn行每行描述了一个结点的状况,包含三个整数,整数之间用空格(一个或多个)分隔,其中:第一个数为居民人口数;第二个数为左链接,为00表示无链接;第三个数为右链接,为00表示无链接。
【输出】
一个整数,表示最小距离和。
【输入样例】
5 13 2 3 4 0 0 12 4 5 20 0 0 40 0 0
【输出样例】
81
#include <bits/stdc++.h> using namespace std; struct Node { int value; // 值 int left; // 左子 int right; // 右子 int dad; // 父亲 int level; // 层级 }; void ShowTree(const vector<Node> &a) { cout << "value, left, right, data, level" << endl; for (int i = 1; i < a.size(); i++) { cout << a[i].value << " "; cout << a[i].left << " "; cout << a[i].right << " "; cout << a[i].dad << " "; cout << a[i].level << endl; } } int FindRoot(const vector<Node> &a) { for (int i = 1; i < a.size(); i++) { if (a[i].dad == 0) { return i; } } return 0; } void SetLevel(vector<Node> &a, int index, int level) { if (index > 0) { a[index].level = level; SetLevel(a, a[index].left, level + 1); SetLevel(a, a[index].right, level + 1); } } int CalcDist(const vector<Node> &a, int i, int j) { if (i == j) { return 0; } else if (a[i].level < a[j].level) { int dist = CalcDist(a, i, a[j].dad); return dist + 1; } else { int dist = CalcDist(a, a[i].dad, j); return dist + 1; } } void CalcDist(vector<vector<int> > &d, const vector<Node> &a) { for (int i = 1; i < d.size(); i++) { for (int j = i; j < d.size(); j++) { d[i][j] = d[j][i] = CalcDist(a, i, j); } } } int FindBest(const vector<vector<int> > &d, const vector<Node> &a) { int mn = INT_MAX; for (int i = 1; i < d.size(); i++) { int dist = 0; for (int j = 1; j < d.size(); j++) { dist += d[i][j] * a[j].value; } if (mn > dist) { mn = dist; } } return mn; } int main() { // freopen("1.txt", "r", stdin); int n; cin >> n; vector<Node> a(n + 1); for (int i = 1; i <= n; i++) { cin >> a[i].value; cin >> a[i].left; cin >> a[i].right; a[a[i].left].dad = i; a[a[i].right].dad = i; } int root = FindRoot(a); // cout << "root=" << root << endl; SetLevel(a, root, 0); // ShowTree(a); vector<vector<int> > d(n + 1, vector<int>(n + 1)); CalcDist(d, a); // 计算所有两点间的距离 cout << FindBest(d, a); return 0; }