图论练习题——医院设置
目录:
·题目描述
·题目分析
·思路分析
·代码实现
·总结
·题目描述:
设有一棵二叉树,如图:
其中,圈中的数字表示结点中居民的人口。圈边上数字表示结点编号,现在要求在某个结点上建立一个医院,使所有居民所走的路程之和为最小,同时约定,相邻接点之间的距离为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
I can do all things