题目描述
设有一棵二叉树,其中圈中的数字表示结点居民的人口,圈边上的数字表示结点的编号。现在要求在某个结点上建立一个医院,使所有居民所走的路径之和为最小,同时约定,相邻接点之间的距离为1,就本图而言,若医院建在1处,则距离和=4+12+2*20+2*40=136,若医院建在3处,则距离和=4*2+13+20+40=81,…
输入格式
其中第一行一个整数n,表示树的结点数(n<=100)。接下来的N行每行描述了一个结点的状况,包括三个整数,整数之间用空格(一个或多 个)分隔,其中:第一个数为居民人口数;第二个数为左链接,为0表示无链接;第三个数为右链接。
输出格式
只有一个整数,表示最小距离和。
样例输入
5
13 2 3
4 0 0
12 4 5
20 0 0
40 0 0
样例输出
81
代码
1 PROGRAM p319;
2 var dist:array[0..100,0..100]of longint;
3 a:array[0..100]of longint;
4 n:longint;
5
6 procedure init;
7 var i,j,x,y,z:longint;
8 begin
9 readln(n);
10 fillchar(dist,sizeof(dist),0);
11 for i:=1 to n do
12 begin
13 readln(x,y,z);
14 a[i]:=x;
15 if y<>0 then
16 begin
17 dist[i,y]:=1;
18 dist[y,i]:=1;
19 end;
20 if z<>0 then
21 begin
22 dist[i,z]:=1;
23 dist[z,i]:=1;
24 end;
25 end;
26 end;
27
28 procedure main;
29 var i,j,k:longint;
30 begin
31 for k:=1 to n do
32 for i:=1 to n do
33 if i<>k then
34 for j:=1 to n do
35 if (i<>j)and(k<>j)then
36 if (dist[i,k]<>0)and(dist[k,j]<>0) then
37 if (dist[i,j]>dist[i,k]+dist[k,j])or (dist[i,j]=0) then
38 dist[i,j]:=dist[i,k]+dist[k,j];
39 end;
40
41 procedure print;
42 var i,j,s,ans:longint;
43 begin
44 ans:=maxlongint;
45 for i:=1 to n do
46 begin
47 s:=0;
48 for j:=1 to n do
49 if i<>j then
50 s:=s+dist[j,i]*a[j];
51 if s<ans then ans:=s;
52 end;
53 writeln(ans);
54 end;
55
56 begin
57 // assign(input,'input.txt');
58 // reset(input);
59 // assign(output,'output.txt');
60 // rewrite(output);
61 init;
62 main;
63 print;
64 // close(input);
65 // close(output);
66 end.
题目分析
虽然这个题目表象上来看与树有些关联,仔细分析一下不难发现,其实他就是一个简单的单源最短路径算法,在这里我使用的是Floyd算法
不过需要注意的地方,在进行最后输出时要将所有的点点路径长度循环一遍,并将该村庄的人数乘以路径的长度,将所有的长度积之和相加,
求得一个最小的即可。
(由JackerJay原创,转载请注明出处)

浙公网安备 33010602011771号