医院设置

本文介绍了一个基于最短路径算法解决的问题:寻找图中从任一点出发到达其他各点最小代价总和的节点。通过Floyd算法进行路径优化,并结合输入数据特点实现了高效的求解。
#include<bits/stdc++.h>
using namespace std;
int a[101];
int g[101][101];
int main()
{
int n,k,l,r,b,c;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
g[i][j]=1000000;
for(int i=1;i<=n;i++)
{
g[i][i]=0;
cin>>a[i]>>l>>r;
if(l>0) g[i][l]=g[l][i]=1;
if(r>0) g[i][r]=g[r][i]=1;
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
if(i!=k)
for(int j=1;j<=n;j++)
if(i!=j&&k!=j&&g[i][k]+g[k][j]<g[i][j])
g[i][j]=g[i][k]+g[k][j];
b=0x7fffffff;
for(int i=1;i<=n;i++)
{
c=0;
for(int j=1;j<=n;j++) c+=g[i][j]*a[j];
if(c<b) b=c;
}
cout<<b<<endl;
return 0;
}
洛谷上的“医院设置”题目(P1364)描述如下:设有一棵二叉树,圈中的数字表示结点中居民的人口,圈边上数字表示结点编号,要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定相邻接点之间的距离为 1。例如,若医院建在 1 处,则距离和 =4 + 12 + 2×20 + 2×40 = 136;若医院建在 3 处,则距离和 =4×2 + 13 + 20 + 40 = 81 [^1][^2]。 题解方面,一种思路是通过遍历每个节点作为医院的选址,然后计算所有居民到该医院的路程之和。最后求最短路径时,要记得将 total 初始化为 0,以下是一段示例代码: ```cpp for(int i = 1; i <= n; i++){ total = 0; // 初始化以丢弃以前的值 for(int j = 1; j <= n; j++){ // 遍历结点求将医院设在此地的路径 total += lu_jing[i][j] * a[j]; } minn = min(total, minn); // 如果 total 小于 minn,则重新赋值,否则不变 } ``` [^4] 还有一种使用广度优先搜索(BFS)的题解,核心代码如下: ```c void bfs(int map[][6], int s_node, int flag[], int num) { flag[s_node] = 1; if(map[s_node][1] != 0 && flag[map[s_node][1]] == 0) { // 左孩子且没有被访问过 int loc = map[s_node][1]; result += num * map[loc][0]; flag[loc] = 1; bfs(map, loc, flag, num + 1); } if(map[s_node][2] != 0 && flag[map[s_node][2]] == 0) { // 右孩子 int loc = map[s_node][2]; result += num * map[loc][0]; flag[loc] = 1; bfs(map, loc, flag, num + 1); } if(map[s_node][3] != 0 && flag[map[s_node][3]] == 0) { // 父亲节点 int loc = map[s_node][3]; result += num * map[loc][0]; flag[loc] = 1; bfs(map, loc, flag, num + 1); } } ``` 该代码中 bfs 函数的参数分别是邻接表、开始节点的编号、flag 数组、节点权值应该乘的倍数 num。先将当前节点的 flag 值设为 1,再分别对其左右孩子、父亲节点进行 bfs,如果节点符合要求,就从这个节点开始继续进行 bfs,在进行下一次递归时,由于相对位置的增加,num 应该递增,同时将该节点的 flag 值设为 1 表示已经被访问过,最后得到的 result 的值就是以这个节点为重心所得的计算结果 [^5]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值