题目描述
设有一棵二叉树,如图:
其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为 11。如上图中,若医院建在1 处,则距离和 =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。
输入格式
第一行一个整数 �n,表示树的结点数。
接下来的 �n 行每行描述了一个结点的状况,包含三个整数 �,�,�w,u,v,其中 �w 为居民人口数,�u 为左链接(为 00 表示无链接),�v 为右链接(为 00 表示无链接)。
输出格式
一个整数,表示最小距离和。
输入输出样例
输入 #1复制
5 13 2 3 4 0 0 12 4 5 20 0 0 40 0 0输出 #1复制
81说明/提示
数据规模与约定
对于 100%100% 的数据,保证 1≤�≤1001≤n≤100,0≤�,�≤�0≤u,v≤n,1≤�≤1051≤w≤105。
1.这道题我采用的算法是dfs。
2.该题的大概题意为:在一棵二叉树中找出一个点使得其他的点到这个点的路程(节点间距离*元素值)之和最小,输出最小距离。
3. 首先,建树,定义一个结构体,包含四个值,一个存储节点的值,一个存储左孩子,一个存储右孩子,一个存储该节点的父节点。输入时,输入每个节点的值还有左右孩子的值,左右孩子的父节点为当前节点的编号。
4.循环遍历每一个节点,调用dfs函数对每一个进行向上,向左,向右搜索,每一步的搜索都用sum累加当前节点的步数*元素值的值。用一个vis数组来进行记忆化。在主函数中判断输出最小的值即可。
#include"stdio.h"
struct node
{
int father,left,right,value;
}t[105];
int sum=999999,ans=999999,vis[105];
int min(int a,int b)
{
if(a>b) return b;
else return a;
}
void dfs(int step,int pos)
{
int i,f,l,r;
sum+=step*t[pos].value;
f=t[pos].father;l=t[pos].left;r=t[pos].right;
if(f&&!vis[f])
{
vis[f]=1;
dfs(step+1,f);
}
if(l&&!vis[l])
{
vis[l]=1;
dfs(step+1,l);
}
if(r&&!vis[r])
{
vis[r]=1;
dfs(step+1,r);
}
}
main()
{
int n,i,j;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%d %d %d",&t[i].value,&t[i].left,&t[i].right);
t[t[i].left].father=t[t[i].right].father=i;
}
for(i=1;i<=n;i++)
{
sum=0;
for(j=0;j<=105;j++)
vis[j]=0;
vis[i]=1;
dfs(0,i);
ans=min(sum,ans);
//printf("%d\n",ans);
}
printf("%d",ans);
}