医院设置
题目描述
设有一棵二叉树,如图:
![](https://i-blog.csdnimg.cn/blog_migrate/de71066f006f6761cbda9c6e0925d545.jpeg)
其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为 $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$。
思路
数据量较小,直接对每个点bfs搜索其父节点和子节点即可。
#include<bits/stdc++.h>
using namespace std;
int n;
struct Node{
int value,left,right,father,len;
}t[1010];
void build(int x,int v,int l,int r){
t[x].value=v;
t[x].left=l;t[x].right=r;
t[l].father=x;
t[r].father=x;
}
long long bfs(int x){
queue<int> q;
bool gone[1010];
memset(gone,0,sizeof(gone));
gone[x]=1;
q.push(x);
long long ans=0;
t[x].len=0;
while(!q.empty()){
int x_now=q.front();
ans+=t[x_now].value*t[x_now].len;
q.pop();
int x_nex[3]={t[x_now].father,t[x_now].left,t[x_now].right};
for(int i=0;i<3;i++){
int x0=x_nex[i];
if(x0!=0&&!gone[x0]){
q.push(x0);
gone[x0]=1;
t[x0].len=t[x_now].len+1;
}
}
}
return ans;
}
int main(){
cin>>n;
t[1].father=0;
for(int i=1;i<=n;i++){
int w,u,v;
cin>>w>>u>>v;
build(i,w,u,v);
}
long long ans=bfs(1);
for(int i=2;i<=n;i++){
ans=min(ans,bfs(i));
}
cout<<ans;
return 0;
}