【题目描述】
设有一棵二叉树,如下图:
[13]1
/
2[4] [12]3
/
4[20] [40]5
其中,圈中数字表示结点居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻结点之间的距离为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
源代码: #include<cstdio> #include<cstring> int n,num,ans=100000000; struct Tree { int sum,left,right,father; }i[220]; void Down(int t,int s) { if (!i[t].left&&!i[t].right) return; num+=s*i[i[t].left].sum+s*i[i[t].right].sum; if (i[t].left) Down(i[t].left,s+1); if (i[t].right) Down(i[t].right,s+1); } void Up(int t,int s) { if (!i[t].father) return; num+=s*i[i[t].father].sum; Up(i[t].father,s+1); if (i[i[t].father].left==t&&i[i[t].father].right) { num+=(s+1)*i[i[i[t].father].right].sum; Down(i[i[t].father].right,s+2); } else if (i[i[t].father].left!=t&&i[i[t].father].left) { num+=(s+1)*i[i[i[t].father].left].sum; Down(i[i[t].father].left,s+2); } } int main() //论"!"的恶心程度。 { memset(i,0,sizeof(i)); scanf("%d",&n); for (int a=1;a<=n;a++) { int t,t1,t2; scanf("%d%d%d",&t,&t1,&t2); i[a].sum=t; i[a].left=t1; i[a].right=t2; i[t1].father=i[t2].father=a; } for (int a=1;a<=n;a++) //一场简单的枚举搜索。 { num=0; Up(a,1); Down(a,1); if (num<ans) ans=num; } printf("%d",ans); return 0; }