【中位数】医院的设置

题目描述

设有一棵二叉树,其中圈中的数字表示结点居民的人口,圈边上的数字表示结点的编号。现在要求在某个结点上建立一个医院,使所有居民所走的路径之和为最小,同时约定,相邻接点之间的距离为1,就本图而言,若医院建在1处,则距离和=4+12+2*20+2*40=136,若医院建在3处,则距离和=4*2+13+20+40=81,…

输入格式

其中第一行一个整数n,表示树的结点数(n<=100)。接下来的N行每行描述了一个结点的状况,包括三个整数,整数之间用空格(一个或多个)分隔,其中:第一个数为居民人口数;第二个数为左链接,为0表示无链接;第三个数为右链接。

输出格式

只有一个整数,表示最小距离和。


又开始回来做水题了。。悲哀的人生。。

一个树上的中位数就完了。先一个dfs与处理出每一个子树的节点总数,和初始状态的ans值。然后又是一个dfs移动到最优解。总时间复杂度O(n)

#include <string>
#include <cstdio>


long ans = 0;


long h[102];
long l[102];
long r[102];
long sum[102];
long total;


long flood(long i,long s)
{
	ans += h[i]*s;
	long rs = 0;
	if (l[i])
		rs += flood(l[i],s+1);
	if (r[i])
		rs += flood(r[i],s+1);
	sum[i] = rs+h[i];
	return sum[i];
}


void dfs(long i)
{
	if (l[i] && sum[l[i]]>(total-sum[l[i]]))
	{
		ans += total-sum[l[i]]-sum[l[i]];
		dfs(l[i]);
	}
	if (r[i] && sum[r[i]]>(total-sum[r[i]]))
	{
		ans += total-sum[r[i]]-sum[r[i]];
		dfs(r[i]);
	}
}


long getint()
{
	char tmp;long rs=0;bool sgn=1;
	do tmp=getchar();
	while (!isdigit(tmp)&&tmp-'-');
	if (tmp=='-'){tmp=getchar();sgn=0;}
	do rs=(rs<<3)+(rs<<1)+tmp-'0';
	while (isdigit(tmp=getchar()));
	return sgn?rs:-rs;
}


int main()
{
	freopen("hospital.in","r",stdin);
	freopen("hospital.out","w",stdout);
	
	long n = getint();
	for (long i=1;i<n+1;i++)
	{
		h[i] = getint();
		l[i] = getint();
		r[i] = getint();
	}
	flood(1,0);
	total = sum[1];
	dfs(1);
	printf("%ld",ans);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值