zoukankan      html  css  js  c++  java
  • 【7011】医院设置

    Time Limit: 1 second
    Memory Limit: 64 MB

    【问题描述】

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

    【输入格式】

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

    【输出格式】

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

    【输入样例1】

        5
        13 2 3
        4 0 0
        12 4 5
        20 0 0
        40 0 0
    

    【输出样例1】

        81
    

    【题解】

    首先,在输入二叉树的时候,记录下父亲结点和子结点的连通情况。若两点连通,则置bo[i][j]为1。然后用floyed算法算出任意两个结点之间的距离(按照求最短路的办法来求就可以了)。

    然后进行枚举,枚举医院设置在第i个结点的情况。for一遍其他位置,用一个sum来进行累加,sum+=a[j]*bo[i][j]。然后尝试更新最小距离。

    最后输出就可以了。

    【代码】

    #include <cstdio>
    #include <cstring>
    
    int n,a[120],bo[120][120],min_n = 2100000000;
    
    void input_data()
    {
        memset(bo,0,sizeof(bo));
        scanf("%d",&n);
        for (int i = 1;i <= n;i++)
            {
                int l,r;
                scanf("%d%d%d",&a[i],&l,&r);
                if (l!=0)
                    bo[i][l] =1,bo[l][i] = 1; //这个连通情况是双向的。
                if (r!=0)
                    bo[i][r] = 1,bo[r][i] = 1;
            }
    }
    
    void get_ans()
    {
        for (int k = 1;k <= n;k++) //利用floyed算法算出任意两点之间的距离;(要按照求最短路的方法求)
            for (int i = 1;i <= n;i++)
                for (int j = 1;j <= n;j++)
                    if ((bo[i][k] >0) && (bo[k][j] >0))
                        {
                            if (bo[i][j] == 0)
                                bo[i][j] = bo[i][k] + bo[k][j];
                                    else
                                        if (bo[i][j] > bo[i][k]+bo[k][j])
                                            bo[i][j] = bo[i][k]+bo[k][j];
                        }
        for (int i = 1;i <= n;i++) //枚举医院设置在第i个结点。
            {
                int sum = 0;
                for (int j = 1;j <= n;j++)
                    if (j != i)
                        sum += bo[i][j]*a[j]; //bo[i][j]即表示其他结点到i结点的距离
                if (sum < min_n) //尝试更新累加的最小值。
                    min_n = sum;
            }
    }
    
    void output_ans()
    {
        printf("%d
    ",min_n);
    }
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        input_data();
        get_ans();
        output_ans();
        return 0;
    }
    


     

  • 相关阅读:
    装饰器函数(一)
    面向对象的初阶复习
    内置函数/反射/内置方法(单例类面)
    property特殊属性/类方法/静态方法
    多态/封装
    接口类抽象类
    初始继承之顺序/深度优先及广度优先
    类涉及的空间关系及组合(可变项地址面)
    <head></head>
    让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632412.html
Copyright © 2011-2022 走看看