天天看點

【資料結構】 醫院選址

問題描述

在某個鎮中包含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)輸出建立醫院的村莊名稱

【資料結構】 醫院選址

繼續閱讀