洛谷P1364 医院设置
这题是个树类题目,但是咱这次不用bfs不用dfs,咱用floyd写
记得把自身置于0就好了,为什么不把自身弄成INF呢,就单纯因为这题里面,树结点自身权重代表人数,最后要×起来,所以如果置于INF会变得无穷大
题目描述
设有一棵二叉树,如图:

其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为 \(1\)。如上图中,若医院建在 \(1\) 处,则距离和 \(=4+12+2\times20+2\times40=136\);若医院建在 \(3\) 处,则距离和 \(=4\times2+13+20+40=81\)。
输入格式
第一行一个整数 \(n\),表示树的结点数。
接下来的 \(n\) 行每行描述了一个结点的状况,包含三个整数 \(w, u, v\),其中 \(w\) 为居民人口数,\(u\) 为左链接(为 \(0\) 表示无链接),\(v\) 为右链接(为 \(0\) 表示无链接)。
输出格式
一个整数,表示最小距离和。
输入输出样例 #1
输入 #1
5
13 2 3
4 0 0
12 4 5
20 0 0
40 0 0
输出 #1
81
说明/提示
数据规模与约定
对于 \(100\%\) 的数据,保证 \(1 \leq n \leq 100\),\(0 \leq u, v \leq n\),\(1 \leq w \leq 10^5\)。
好的接下来是代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int INF = 1e18;
void solve() {
int n;
cin >> n;
vector<int> weight(n + 1);
vector<vector<int>> a(n + 1, vector<int>(n + 1, INF));
// 初始化自身到自身的距离为0
for (int i = 1; i <= n; i++) {
a[i][i] = 0;
}
// 读取输入,构建无向边(距离为1)
for (int i = 1; i <= n; i++) {
int w, l, r;
cin >> w >> l >> r;
weight[i] = w;
// 左子节点存在,设置无向边距离为1
if (l != 0) {
a[i][l] = 1;
a[l][i] = 1;
}
// 右子节点存在,设置无向边距离为1
if (r != 0) {
a[i][r] = 1;
a[r][i] = 1;
}
}
// Floyd
for (int k = 1; k <= n; k++) {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (a[i][k] != INF && a[k][j] != INF) {
a[i][j] = min(a[i][j], a[i][k] + a[k][j]);
}
}
}
}
// 枚举每个节点作为医院,计算最小总路程
int ans = INF;
for (int i = 1; i <= n; i++) {
int sum = 0;
for (int j = 1; j <= n; j++) {
sum += weight[j] * a[j][i];
}
ans = min(ans, sum);
}
cout << ans << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
int T=1;
while(T--)
solve();
return 0;
}

浙公网安备 33010602011771号