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

    【问题描述】

           设有一棵二叉树,如图5-1:

                                                                                                        131

                                                                              /  

                                                                            24  123

                                                                                    /  

                                                                               420 405

        其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为l。如上图中,若医院建在:

    【输入】

        第一行一个整数n,表示树的结点数。(n≤100)

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

    【输出】

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

    【样例】

           hospital.in                          hospital.out

           5                                        81

           13 2 3

           4 0 0

           12 4 5

           20 0 0

           40 0 0

    【知识准备】

           图的遍历和最短路径。

    【算法分析】

           本题的求解任务十分明了:求一个最小路径之和。

           根据题意,对n个结点,共有n个路径之和:用记号Si表示通向结点i的路径之和,则,其中Wj为结点j的居民数,g(i,j)为结点j到结点i的最短路径长度。下面表中反映的是样例的各项数据:

    j

    g(i,j)

    i

    1

    2

    3

    4

    5

    Si

    1

    0

    1

    1

    2

    2

    0×13+1×4+1×12+2×20+2×40=136

    2

    1

    0

    2

    3

    3

    1×13+0×4+2×12+3×20+3×40=217

    3

    1

    2

    0

    1

    1

    1×13+2×4+0×12+1×20+1×40=81

    4

    2

    3

    1

    0

    2

    2×13+3×4+1×12+0×20+2×40=130

    5

    2

    3

    1

    2

    0

    2×13+3×4+1×12+2×20+0×40=90

           从表中可知S3=81最小,医院应建在3号居民点,使得所有居民走的路径之和为最小。

           由此可知,本题的关键是求g[i,j],即图中任意两点间的最短路径长度。

           求任意两点间的最短路径采用下面的弗洛伊德(Floyd)算法。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #define M 110
    #define INF 999999
    using namespace std;
    int f[M][M],a[M],dis[M],n;
    int main()
    {
        freopen("jh.in","r",stdin);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
            f[i][j]=INF;
        for(int i=1;i<=n;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[i]=x;
            f[i][y]=f[y][i]=1;
            f[i][z]=f[z][i]=1;
        }
        for(int k=1;k<=n;k++)
          for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
              if(i!=j&&j!=k&&i!=k)
                f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
            if(i!=j)
              dis[i]+=f[i][j]*a[j];
        sort(dis+1,dis+n+1);
        printf("%d",dis[1]);
        return 0;
    }
    View Code
  • 相关阅读:
    Python写出LSTM-RNN的代码
    TensorFlow 实现 RNN 入门教程
    RNN与应用案例:注意力模型与机器翻译
    RNN入门
    内积(又名点积)
    词袋模型(BOW, bag of words)
    softmax
    Dropout
    随机梯度下降法
    L1范式和L2范式
  • 原文地址:https://www.cnblogs.com/harden/p/5596801.html
Copyright © 2011-2022 走看看