[数据结构]27.交通咨询系统——最低花费 (Floyd算法)

27.交通咨询系统——最低花费(***)

描述

设计一个交通咨询系统,能让旅客咨询从任一个城市到另一个城市之间的最低花费。

(1)顶点表示城市,边表示城市之间的交通关系,边的权值表示两个城市之间交通所需要的时间。

(2)图采用邻接矩阵存储结构实现。

(3)输出两个城市之间的最低花费。

(4)在主函数中调用菜单函数调试程序。

初始代码:

#include <stdio.h>
#include<malloc.h>
#include <stdlib.h>
#define MaxVerNum 30//定义存储的最大个数
#define NIF 32767   //定义无穷大
#define false 0
#define true 1
typedef char VertexType; //定义顶点表类型是字符型
typedef int Edgetype;

/**建立结构体**/
typedef struct {
	VertexType vexs[MaxVerNum];/*顶点表*/
	Edgetype edges[MaxVerNum][MaxVerNum]; //边表
	int n, e;  //顶点数和边数
} MGraph;

int menu_select()
{
	int sn;
	printf("-----------交通咨询系统——最低花费----------------------\n");
	printf("1构建图\n");
	printf("2输出两个城市之间的最低花费\n");
	printf("3退出\n");
	printf("  请选择1--3:  ");

	for(;;)		//菜单功能选择
	{
		scanf("%d",&sn);
		getchar();
		if(sn<1 || sn>3)
			printf("\n\t 输入选择错误,请重新选择 1--3: ");
		else
			break;
	}
	return sn;
}

/*TODO: 创建邻接矩阵
 功能描述: 功能描述:创建邻接矩阵,初始设置节点自己到自己为0,其他为NIF,创建边时,根据输入设置权值。
 参数说明:MG-MGraph型指针参数
 返回值说明:无
*/
void CreatGraph(MGraph *G) { /**接口参数:图的结构体指针**/
	int i, j,weight,  k;
	printf("请输入城市数和路线数(比如:4,5):\t");
	scanf("%d,%d", &(G->n), &(G->e));  //顶点数及边数
	printf("\n请输入城市数据:\t");
	for (i = 0; i < G->n; i++) {
		scanf("%s", &(G->vexs[i]));/**输入顶点信息**/
	}
	
	for (k = 0; k < G->e; k++) {
		printf("\n请输入存在路线的两个城市以及票价(比如:2,3,4):\t");
		scanf("%d,%d,%d", &i, &j ,&weight);/**输入边的信息**/
		
	}
}
/*TODO: Floyd求得两个顶点间最短路径
 功能描述:用Floyd算法求出from到to两点最小路径并返回(from,to是用创建图时,存入的数组的下标表示)
 参数说明:G-MGraph型指针参数
       from-int型 最短路径开始顶点
       to-int型  最短路径结束顶点
 返回值说明:int型最短路径
 */
int Floyd(MGraph *G, int from, int to) {
	
}
/**************主函数部分***************/
void main()
{
	int from, to, result;
	MGraph *S;
	S = (MGraph*) malloc(sizeof(MGraph));
	for(;;)	 // 无限循环,选择0 退出
	{
		switch(menu_select())
		{
			case 1:
				CreatGraph(S);
				break;
			case 2:
				printf("请输入两个城市根据从0开始(比如0,1)\n");
				scanf("%d,%d", &from, &to);
				result = Floyd(S, from, to);
				printf("最低花费是  %d \n", result);
				break;
			case 3:
				printf(" 再见!\n");
				return;
		} // switch语句结束
	} // for循环结束
} // main()函数结束

思路:

本题采用Floyd算法,思路较为简单,以邻接矩阵存储的无向网为初始状态,此时矩阵中的每个值都代表两个顶点间的路径长度,Floyd算法的思路是在每两个顶点(源点和重点)间增加新的顶点(借助其他顶点)进行试探,试探增加顶点后的路径长度是否会变短,增加顶点后若变短,则用增加顶点后的路径长度取代原路径长度。对于原表中的每个顶点都要进行试探,确定增加了它们后路径是否会变短,因此有状态转移方程

G->edges[i][j] = G->edges[i][k] + G->edges[k][j]

其中k取遍所有顶点。

更具体的解释如下:Yvgvkt.png

Yv2pp8.png

(更为详细的解释,移步至——https://www.cnblogs.com/wangyuliang/p/9216365.html)

实现:

#include <stdio.h>
#include<malloc.h>
#include <stdlib.h>
#define MaxVerNum 30//定义存储的最大个数
#define NIF 32767   //定义无穷大
#define false 0
#define true 1
typedef char VertexType; //定义顶点表类型是字符型
typedef int Edgetype;

/**建立结构体**/
typedef struct
{
    VertexType vexs[MaxVerNum];/*顶点表*/
    Edgetype edges[MaxVerNum][MaxVerNum]; //边表
    int n, e;  //顶点数和边数
} MGraph;

int menu_select()
{
    int sn;
    printf("-----------交通咨询系统——最低花费----------------------\n");
    printf("1构建图\n");
    printf("2输出两个城市之间的最低花费\n");
    printf("3退出\n");
    printf("  请选择1--3:  ");

    for(;;)		//菜单功能选择
    {
        scanf("%d",&sn);
        getchar();
        if(sn<1 || sn>3)
            printf("\n\t 输入选择错误,请重新选择 1--3: ");
        else
            break;
    }
    return sn;
}

/*TODO: 创建邻接矩阵
 功能描述: 功能描述:创建邻接矩阵,初始设置节点自己到自己为0,其他为NIF,创建边时,根据输入设置权值。
 参数说明:MG-MGraph型指针参数
 返回值说明:无
*/
void CreatGraph(MGraph *G)   /**接口参数:图的结构体指针**/
{
    int i, j,weight,  k;
    printf("请输入城市数和路线数(比如:4,5):\t");
    scanf("%d,%d", &(G->n), &(G->e));  //顶点数及边数
    printf("\n请输入城市数据:\t");
    for (i = 0; i < G->n; i++)
    {
        scanf("%s", &(G->vexs[i]));/**输入顶点信息**/
    }
    for(i=0;i<G->n;i++)
    {
        for(j=0;j<G->n;j++)
        {
            if(i == j)
            {
                G->edges[i][j] = 0;
            }
            else
            {
                G->edges[i][j] = NIF;
            }
        }
    }
    for (k = 0; k < G->e; k++)
    {
        printf("\n请输入存在路线的两个城市以及票价(比如:2,3,4):\t");
        scanf("%d,%d,%d", &i, &j,&weight); /**输入边的信息**/
        G->edges[i][j] = weight;
        G->edges[j][i] = weight;
    }
}
/*TODO: Floyd求得两个顶点间最短路径
 功能描述:用Floyd算法求出from到to两点最小路径并返回(from,to是用创建图时,存入的数组的下标表示)
 参数说明:G-MGraph型指针参数
       from-int型 最短路径开始顶点
       to-int型  最短路径结束顶点
 返回值说明:int型最短路径
 */
int Floyd(MGraph *G, int from, int to)
{
    int i,j,k;
    for(k=0;k<G->n;k++)
    {
        for(i=0;i<G->n;i++)
        {
            for(j=0;j<G->n;j++)
            {
                if(G->edges[i][j] > G->edges[i][k] + G->edges[k][j])
                {
                    G->edges[i][j] = G->edges[i][k] + G->edges[k][j];//Floyd算法的状态转移方程
                }
            }
        }
    }
    return G->edges[from][to];
}
/**************主函数部分***************/
int main()
{
    int from, to, result;
    MGraph *S;
    S = (MGraph*) malloc(sizeof(MGraph));
    for(;;)	 // 无限循环,选择0 退出
    {
        switch(menu_select())
        {
        case 1:
            CreatGraph(S);
            break;
        case 2:
            printf("请输入两个城市根据从0开始(比如0,1)\n");
            scanf("%d,%d", &from, &to);
            result = Floyd(S, from, to);
            printf("最低花费是  %d \n", result);
            break;
        case 3:
            printf(" 再见!\n");
            return 0;
        } // switch语句结束
    } // for循环结束
} // main()函数结束

测试输入:

1,12,14 A B C D H L K J I E F G 0,1,1 1,2,1 2,3,1 3,4,1 4,5,1 5,6,1 6,7,1 7,8,1 8,9,1 9,0,1 0,3,2 0,10,1 10,11,2 11,5,1 2 3,9 3

测试输出:

答案输出:-----------交通咨询系统——最低花费----------------------
1构建图
2输出两个城市之间的最低花费
3退出
  请选择1--3:  请输入城市数和路线数(比如:4,5):	
请输入城市数据:	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	
请输入存在路线的两个城市以及票价(比如:2,3,4):	-----------交通咨询系统——最低花费----------------------
1构建图
2输出两个城市之间的最低花费
3退出
  请选择1--3:  请输入两个城市根据从0开始(比如0,1)
最低花费是  3 
-----------交通咨询系统——最低花费----------------------
1构建图
2输出两个城市之间的最低花费
3退出
  请选择1--3:   再见!
posted @ 2020-05-23 16:55  Desola  阅读(1286)  评论(0)    收藏  举报