一、问题描述
有n个村庄,现要从这n个村庄中选择一个村庄新建一所医院,使其余的村庄到这所医院的距离总体来说较短,设计较合理。
可以用Floyd算法实现。
二、简单声明
N表示村庄所有数量(村庄1,村庄2,村庄3....村庄N)
maps[N][N]是村庄之间的距离,如下图,村庄1到村庄2距离为12,村庄1到村庄6距离为16等。
图示例 maps[N][N]
shorts[N][N]是存村庄之间最短距离,如下图,村庄1到村庄3最短距离为22,村庄2到村庄6最短距离为7
三、存储数据
存储数据到maps里可以采取读取文件或者自行输入,均可。
1.读取文件数据
文件内容:
1 2 12
1 6 16
1 7 14
2 3 10
2 6 7
3 4 3
3 5 5
3 6 6
4 5 4
5 6 2
5 7 8
6 7 9
0
void Out_datas(){
FILE *fp;
fp=fopen("test.txt","r");
int i,j,cost;
fscanf(fp,"%d%d%d",&i,&j,&cost);
while(i!=0){
maps[i][j]=cost;
maps[j][i]=cost;
fscanf(fp,"%d%d%d",&i,&j,&cost);
}
}
2.自己输入数据
void Scanf_datas(){
printf("依次输入位置n1和位置n2以及距离(以 0 0 0 结束):\n");
int i,j,cost;
while(i!=0){
scanf("%d%d%d",&i,&j,&cost);
maps[i][j]=cost;
maps[j][i]=cost;
}
}
四、最短距离
Floyd核心算法
void Floyd(){
int i,j,k,min;
for(i=1;i<=N;i++){
for(j=1;j<=N;j++)
shorts[i][j]=maps[i][j];
}
for(k=1;k<=N;k++){
for(i=1;i<=N;i++){
for(j=1;j<=N;j++){
min=shorts[i][j];
if(i==j) continue;
if(shorts[i][k]+shorts[k][j]<min){
min=shorts[i][k]+shorts[k][j];
shorts[i][j]=min;
}
}
}
}
}
五、其余函数
void Dis_datas(){
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
printf("%3d\t",maps[i][j]);
}
printf("\n");
}
printf("\n");
}
void Dis_shorts(){
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
printf("%3d\t",shorts[i][j]);
}
printf("\n");
}
printf("\n");
}
六、总代码
#include<stdio.h>
#include<stdlib.h>
#define N 7
int maps[N+1][N+1];
int shorts[N+1][N+1];
void Init_datas(){
for(int i=0;i<=N;i++){
for(int j=0;j<=N;j++){
maps[i][j]=999;
}
}
}
void Init_shorts(){
for(int i=0;i<=N;i++){
for(int j=0;j<=N;j++){
shorts[i][j]=999;
}
}
}
void Out_datas(){
FILE *fp;
fp=fopen("test.txt","r");
int i,j,cost;
fscanf(fp,"%d%d%d",&i,&j,&cost);
while(i!=0){
maps[i][j]=cost;
maps[j][i]=cost;
fscanf(fp,"%d%d%d",&i,&j,&cost);
}
}
void Scanf_datas(){
printf("依次输入位置n1和位置n2以及距离(以 0 0 0 结束):\n");
int i,j,cost;
while(i!=0){
scanf("%d%d%d",&i,&j,&cost);
maps[i][j]=cost;
maps[j][i]=cost;
}
}
void Dis_datas(){
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
printf("%3d\t",maps[i][j]);
}
printf("\n");
}
printf("\n");
}
void Dis_shorts(){
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
printf("%3d\t",shorts[i][j]);
}
printf("\n");
}
printf("\n");
}
void Floyd(){
int i,j,k,min;
for(i=1;i<=N;i++){
for(j=1;j<=N;j++)
shorts[i][j]=maps[i][j];
}
for(k=1;k<=N;k++){
for(i=1;i<=N;i++){
for(j=1;j<=N;j++){
min=shorts[i][j];
if(i==j) continue;
if(shorts[i][k]+shorts[k][j]<min){
min=shorts[i][k]+shorts[k][j];
shorts[i][j]=min;
}
}
}
}
}
int Choose(){
int tmp,min=999;
int all[N+1];
for(int i=1;i<=N;i++){
int sum=0;
for(int j=1;j<=N;j++){
if(i==j) continue;
sum=sum+shorts[i][j];
}
all[i]=sum;
if(sum<min){
min=sum;
tmp=i;
}
}
for(i=1;i<=N;i++)
printf("所有到第%d个地方距离为:%d\n",i,all[i]);
return tmp;
}
int main(){
int flag=0;
while(flag!=99){
printf("**************************************************\n");
printf("1.读取文件数据\n");
printf("2.自己输入数据\n");
printf("3.求每个顶点到其余顶点的最短距离(Floyd算法)\n");
printf("4.求选择合理的医院\n");
printf("99.退出\n");
printf("**************************************************\n");
printf("请输入:");
scanf("%d",&flag);
printf("**************************************************\n");
switch(flag){
case 1:
Init_datas();
Out_datas();
Dis_datas();
break;
case 2:
Init_datas();
Scanf_datas();
Dis_datas();
break;
case 3:
Init_shorts();
Floyd();
Dis_shorts();
break;
case 4:
int tmp;
tmp=Choose();
printf("选择%d\n",tmp);
break;
case 99:
break;
}
}
return 0;
}
七、结果分析
输入1,调用Out_datas()函数,先读取文件内容,存到maps[N][N]
输入3,调用Floyd()函数,求得每对村庄之间的最短距离,存入shorts[N][N]
输入4,选择其余村庄到某个村庄总距离最小的村庄,上面数据测得是村庄5,故选村庄5作为医院,可以使得距离总体最小。