天天看点

【数据结构】 医院选址

问题描述

在某个镇中包含n个村庄,现要从这n个村庄中选择一个村庄建立一所医院,这所医院应建在哪个村庄,才能使离医院最远的村庄到医院最近?(Floyd算法)

一堆废话

很久没有更新博客了,小白刚刚历经考试周的打击,百废待兴,赶紧跑来CSDN和小伙伴们取暖安慰受伤的心灵。近期会陆续写四篇数据结构课设的博客,然后再写两篇编写小游戏的博客,一个是基于Python的飞机大战,另一个是基于C++并在funcode上完成的海底世界游戏。

数据描述

(1)首先定义一个结构体,存放弧的权值信息。

#define Size 20
//定义弧的权值信息
typedef struct Arccell
{
    int adj; //权值
} Arccell, AdjMatrix[Size][Size]; //图的邻接矩
           

(2)再定义一个结构体,存放村庄信息。

//定义结点信息
typedef struct VertexInfo
{
    char name[20]; //结点[村庄]名称
    int position; //定点编号
} VertexInfo;
           

(3)再定义一个图结构体,存放图的信息。

#define Size 20
//图的结构体 
typedef struct Mgraph
{
    VertexInfo vexs[Size];//顶点数组
    AdjMatrix arcs;//邻接矩阵
    int vernum,arcnum;//分别指定顶点数和边数
} Mgraph;
           

程序代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define INFINITY 1000000
#define Size 20

//定义弧的权值信息
typedef struct Arccell
{
    int adj; //权值
} Arccell, AdjMatrix[Size][Size]; //图的邻接矩阵
//定义结点信息
typedef struct VertexInfo
{
    char name[20]; //结点[村庄]名称
    int position; //定点编号
} VertexInfo;
//图的结构体 
typedef struct Mgraph
{
    VertexInfo vexs[Size];//顶点数组
    AdjMatrix arcs;//邻接矩阵
    int vernum,arcnum;//分别指定顶点数和边数
} Mgraph;


//对图的初始化
Mgraph InitGraph()
{
    Mgraph c;
    printf("请输入该图的顶点个数和弧的个数:\n");
    printf("顶点个数:");
    scanf("%d",&c.vernum);
    printf("弧的个数:");
    scanf("%d",&c.arcnum);
    //依次设置顶点编号
    for(int i=0; i<c.vernum; i++)
    {
        c.vexs[i].position=i;
    }
    printf("请依次输入各个村庄的名称:\n");
    for(int i=0;i<c.vernum;i++)
    {
        printf("村庄%d\t",i);
        scanf("%s",&c.vexs[i].name);

    }
    //依次设置各弧的信息
    for(int i=0; i<c.vernum; i++)
    {
        //先初始化邻接矩阵,相同点设置为0,其他全部设置为INFINITY(无穷大)
        for(int j=0; j<c.vernum; j++)
        {
            if(i==j)
            c.arcs[i][j].adj=0;
            c.arcs[i][j].adj=INFINITY;
        }
    }
    //再依次输入需要设置的权值
    int i,j,k;
    printf("请输入两端顶点和弧长(输入3个0结束):\n");
    while(scanf("%d%d%d",&i,&j,&k))
    {
        if(i==0&&j==0&k==0)
            break;
        c.arcs[i][j].adj=k;
    }
    return c;
}

//输出邻接矩阵
void PrintMatrix(Mgraph c)
{
    printf("该图的邻接矩阵如下所示:\n");
    int count=0; //用于计数
    for(int i=0; i<c.vernum; i++)
        for(int j=0; j<c.vernum; j++)
        {
            if(c.arcs[i][j].adj==INFINITY)
                printf("   #");
            else
                printf("%4d",c.arcs[i][j].adj);
            count++;
            if(count%c.vernum==0)
                printf("\n");
        }
}

//求最短路径 
void ShortestPath_Floyd(Mgraph G,int dis[][Size])
{
    //用floyd算法求有向网G中各对定点v和w之间的最短路径及其带权长度dis[v][w]
    for(int v=0; v<G.vernum; v++)
        for(int w=0; w<G.vernum; w++)
        {
            //对各结点之间初始化已知距离
            dis[v][w]=G.arcs[v][w].adj;
        }

    for(int k=0; k<G.vernum; k++)
        for(int i=0; i<G.vernum; i++)
            for(int j=0; j<G.vernum; j++)
            {
                if(dis[i][j]>dis[i][k]+dis[k][j])
                {
                    //从v经u到w的路径更短
                    dis[i][j]=dis[i][k]+dis[k][j];
                }
            }

}
//输出距离矩阵
void PrintDis(Mgraph G,int dis[Size][Size])
{
    printf("\n经过Flyod算法之后各顶点之间的距离如下:\n");
    for(int i=0; i<G.vernum; i++)
    {
        for(int j=0; j<G.vernum; j++)
        {
            if(dis[i][j]>=1000000)
                printf("   #");
            else
                printf("%4d",dis[i][j]);

        }
        printf("\n");
    }
}

//求每个点最大路径 
void GetDegree(Mgraph G,int dis[Size][Size],int degree[])
{
    for(int i=0;i<G.vernum;i++)
    {
        int max=dis[0][i];
        for(int j=0;j<G.vernum;j++)
        {
            if(dis[j][i]>max)
                max=dis[j][i];
        }
        degree[i]=max;
    }
}

int main()
{
    printf("**********欢迎使用医院选址系统*********\n");
    Mgraph c=InitGraph();
    system("cls"); 

    //输出邻接矩阵
    PrintMatrix(c);

    //定义距离数组,调用Floyd算法得到结果
    int dis[Size][Size];
    ShortestPath_Floyd(c,dis);

    //输出各个顶点之间的距离矩阵
    PrintDis(c,dis);

    
    int degree[c.vernum];
    GetDegree(c,dis,degree);


    //得到最小村庄的编号和名称
    int num;
    int min=degree[0];
    for(int i=0;i<c.vernum;i++)
    {
        if(min>degree[i])
            min=degree[i];
    }

    for(int i=0;i<c.vernum;i++)
    {
        if(min==degree[i])
        {
            num=i;
            break;
        }
    }
    printf("医院应该建立在村庄:   %4s \n",c.vexs[num].name);
    return 0;
}
           

测试数据

(1)开始界面

【数据结构】 医院选址

(2)输入图的信息

【数据结构】 医院选址

(3)输出图的邻接矩阵

【数据结构】 医院选址

(4)输出图各顶点的距离矩阵

【数据结构】 医院选址

(5)输出建立医院的村庄名称

【数据结构】 医院选址