图论练习题——医院设置

目录:

·题目描述

·题目分析

·思路分析

·代码实现

·总结


 

·题目描述:

  (洛谷P1364 医院设置)

  设有一棵二叉树,如图:

  

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

  若医院建在1 处,则距离和=4+12+2*20+2*40=136;若医院建在3 处,则距离和=4*2+13+20+40=81

·题目分析:

  这道题是图论算法中的Floyd算法(因为数据太水),下面简单介绍一下Floyd算法:

  在一个无向图上,求任意两点的最短距离,可以使用Floyd算法。算法的大体框架是这样的:  

  如果i,j两点之间存在一点k,使得g[i][k]+g[k][j]<g[i][j],此时更新最小值,g[i][j]=g[i][k]+g[k][j]。并且在写代码时,必须将k放在最外层。 否则会导致g[i][j]过早的被确定下来。

·思路分析:

  对于这道题,可以先跑一遍Floyd,然后枚举每一个结点,求出最小值

·代码实现:

 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 int a[101];
 6 int g[101][101];//g[i][j]表示第i点到第j点的最短距离 
 7 
 8 int main()
 9 {
10     int n,i,j,k,l,r,min,total;
11     //freopen("hospital.in","r",stdin);
12     //freopen("hospital.out","w",stdout);
13     cin>>n;
14     for(i=1;i<=n;i++)//注意初始化
15     {
16         for(j=1;j<=n;j++)
17         {
18             g[i][j]=1000000;
19         }
20     }
21     for(i=1;i<=n;i++)//读入数据,初始化 
22     {
23         g[i][i]=0;
24         cin>>a[i]>>l>>r;
25         if(l>0) g[i][l]=g[l][i]=1;
26         if(r>0) g[i][r]=g[r][i]=1;    
27     }
28     for(k=1;k<=n;k++)//floyd算法,求任意两点间的最短距离 
29     {
30         for(i=1;i<=n;i++)
31         {
32             if(i!=k)
33             {
34                 for(j=1;j<=n;j++)
35                 {
36                     if(i!=j&&k!=j&&g[i][k]+g[k][j]<g[i][j])
37                         g[i][j]=g[i][k]+g[k][j];
38                 }
39             }
40         }
41     }
42     min=0x7fffffff;
43     for(i=1;i<=n;i++)//穷举医院建在n个节点,找出最短距离。 
44     {
45         total=0;//一定要记得清零 
46         for(j=1;j<=n;j++)
47         {
48             total+=g[i][j]*a[j];
49         }
50         if(total<min) min=total;
51     }
52     cout<<min<<endl;
53     return 0; 
54 }

·总结:

  Floyd算法是图论算法中最基础的算法(没有之一),一定要牢记。因为在关键时刻还是可以骗点分的QwQ

原文地址:https://www.cnblogs.com/juruohqk/p/10998538.html