1007: 医院设置
Time Limit: 1 Sec Memory Limit: 65535 MB 64bit IO Format: %lldSubmitted: 3 Accepted: 3
[ Submit][ Status][ Web Board]
Description
一颗二叉树有n(1≤n≤50)个结点,分别编号为1到n,每个结点代表一个居民点,每个居民点都有一定数量的居民(≤100)。现在需要选择一个居民点建一家医院,使得所有居民走的路程之和最小。同时约定,相邻两节点之间的距离为1。
例如对于样例,有5个居民点,每个居民点的居民数量分别为13,4,12,20,40.如果选择居民点1作为医院位置的话,则距离和为4*1+13*0+12*1+20*2+40*2=136;若选择居民点3的话,则距离和为4*2+13*1+12*0+20*1+40*1=81,…
Input
包含多组测试数据。每组测试数据第一行包含一个整数n,接下来的n行,每行3个数据,表示居民点i(1≤i≤n)的居民数和相邻两个居民点编号,如果编号为0表示不存在。
Output
输出最小距离和。
Sample Input
5
13 2 3
4 0 0
12 4 5
20 0 0
40 0 0
Sample Output
81
事先说一下。。。。。。。写的好像有点烦了…………
我最近入门dp 之前好像遇到一个类似的题 当然是要难得多的 (这道题倒是没花我多少时间
当时的题的对象是 整个图 不是树 求这么一个点 其他点到这个点的路径之和最短 真是蒙了个B了 而且数据范围我记得是100W 居然还有个煞笔让我爆搜 我×&&&%¥¥#%%#×%…………
因为之前碰到这个题 所以我真的不愿意爆搜 所以就换一种方法写了一下
这个是树倒是容易些 但我觉得我写的烦了
以下源码 (简单 就不注释了 如果有什么更好的方法 可以的话可以跟我说一下 除了DP…………
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
#define root tree[id]
#define leson tree[ldir]
#define rison tree[rdir]
using namespace std;
const int maxn = 60;
int n, ans;
struct node {
int lson, rson;
int lnum, rnum;
int val, sum;
int key;
};
node tree[maxn];
void FixTree(int id, int dep)
{
int ldir = root.lson, rdir = root.rson;
if (ldir)
FixTree(ldir, dep + 1);
if (rdir)
FixTree(rdir, dep + 1);
root.sum = leson.sum + rison.sum + root.val;
root.lnum = leson.sum;
root.rnum = rison.sum;
root.key = leson.key + rison.key + leson.val * (dep + 1) + rison.val * (dep + 1);
}
void CalcTree(int id, int pre, int pre_key)
{
int ldir = root.lson, rdir = root.rson;
if(id!=1)
root.key = pre_key + pre - root.lnum - root.rnum - root.val;
if (ldir)
CalcTree(ldir, root.rnum + root.val + pre, root.key);
if (rdir)
CalcTree(rdir, root.lnum + root.val + pre, root.key);
ans=min(ans,root.key);
}
int main()
{
tree[0].sum = 0;
while (scanf("%d", &n) != EOF) {
for (int id = 1; id <= n; id++) {
scanf("%d %d %d", &root.val, &root.lson, &root.rson);
root.sum = root.val;
}
for (int id = 0; id <= maxn; id++)
root.key = 0;
FixTree(1, 0);
ans = tree[1].key;
CalcTree(1, 0, tree[1].key);
printf("%d\n", ans);
}
return 0;
}