题目描述
设有一棵二叉树,如图:
其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为 111。如上图中,若医院建在1 处,则距离和 =4+12+2×20+2×40=136=4+12+2\times20+2\times40=136=4+12+2×20+2×40=136;若医院建在 333 处,则距离和 =4×2+13+20+40=81=4\times2+13+20+40=81=4×2+13+20+40=81。
输入格式
第一行一个整数 nnn,表示树的结点数。
接下来的 nnn 行每行描述了一个结点的状况,包含三个整数 w,u,vw, u, vw,u,v,其中 www 为居民人口数,uuu 为左链接(为 000 表示无链接),vvv 为右链接(为 000 表示无链接)。
题目分析:
这个题是一个树形结构的遍历和计算路径值的功能,并求出最小路径值的结果。
- 定义了一些常量和全局变量,包括节点数量、无穷大值、节点值数组、邻接表、标记数组vis和最终结果。
- 一个函数用于初始化程序,读取输入数据并构建树的邻接表表示。
- 一个函数是一个递归函数,用于深度优先搜索树,并计算路径上的节点值乘以路径长度的和。该函数返回当前节点r对应的路径和。
- 一个函数用于遍历所有节点,找到路径和的最小值。
题目代码:
#include <bits/stdc++.h>
const int n=1e2+10;
const int inf=1<<30;
using namespace std;
vector<int> vct[n];
int val[n],n,ans=inf;
bool vis[n];
int main(){
void search();
void init();
int find(int r,int step);
init();
search();
cout<<ans<<endl;
return 0;
}
void init(){
cin>>n;
int w,l,r;
for(int i=1;i<=n;i++){
cin>>w>>l>>r;
val[i]=w;
if(l){
vct[i].push_back(l);
vct[l].push_back(i);
}
if(r){
vct[i].push_back(r);
vct[r].push_back(i);
}
}
}
int find(int r,int step){
if(vis[r]) return 0;
vis[r]=true;
int ans=val[r]*step;
for(int i=0;i<vct[r].size();i++){
int v=vct[r][i];
ans+=find(v,step+1);
}
return ans;
}
void search(){
for(int i=1;i<=n;i++){
memset(vis,false,sizeof(vis));
int tmp=find(i,0);
if(tmp<ans) ans=tmp;
}
}