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,表示樹的結點數(n100n≤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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章