医院设置

来源:互联网 发布:网络黄金未来世界官网 编辑:程序博客网 时间:2024/06/02 20:51
【题目描述】

设有一棵二叉树,如下图:

          [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;}
0 0
原创粉丝点击