zoukankan      html  css  js  c++  java
  • [数据结构]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("-----------交通咨询系统——最低花费----------------------
    ");
    	printf("1构建图
    ");
    	printf("2输出两个城市之间的最低花费
    ");
    	printf("3退出
    ");
    	printf("  请选择1--3:  ");
    
    	for(;;)		//菜单功能选择
    	{
    		scanf("%d",&sn);
    		getchar();
    		if(sn<1 || sn>3)
    			printf("
    	 输入选择错误,请重新选择 1--3: ");
    		else
    			break;
    	}
    	return sn;
    }
    
    /*TODO: 创建邻接矩阵
     功能描述: 功能描述:创建邻接矩阵,初始设置节点自己到自己为0,其他为NIF,创建边时,根据输入设置权值。
     参数说明:MG-MGraph型指针参数
     返回值说明:无
    */
    void CreatGraph(MGraph *G) { /**接口参数:图的结构体指针**/
    	int i, j,weight,  k;
    	printf("请输入城市数和路线数(比如:4,5):	");
    	scanf("%d,%d", &(G->n), &(G->e));  //顶点数及边数
    	printf("
    请输入城市数据:	");
    	for (i = 0; i < G->n; i++) {
    		scanf("%s", &(G->vexs[i]));/**输入顶点信息**/
    	}
    	
    	for (k = 0; k < G->e; k++) {
    		printf("
    请输入存在路线的两个城市以及票价(比如:2,3,4):	");
    		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)
    ");
    				scanf("%d,%d", &from, &to);
    				result = Floyd(S, from, to);
    				printf("最低花费是  %d 
    ", result);
    				break;
    			case 3:
    				printf(" 再见!
    ");
    				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("-----------交通咨询系统——最低花费----------------------
    ");
        printf("1构建图
    ");
        printf("2输出两个城市之间的最低花费
    ");
        printf("3退出
    ");
        printf("  请选择1--3:  ");
    
        for(;;)		//菜单功能选择
        {
            scanf("%d",&sn);
            getchar();
            if(sn<1 || sn>3)
                printf("
    	 输入选择错误,请重新选择 1--3: ");
            else
                break;
        }
        return sn;
    }
    
    /*TODO: 创建邻接矩阵
     功能描述: 功能描述:创建邻接矩阵,初始设置节点自己到自己为0,其他为NIF,创建边时,根据输入设置权值。
     参数说明:MG-MGraph型指针参数
     返回值说明:无
    */
    void CreatGraph(MGraph *G)   /**接口参数:图的结构体指针**/
    {
        int i, j,weight,  k;
        printf("请输入城市数和路线数(比如:4,5):	");
        scanf("%d,%d", &(G->n), &(G->e));  //顶点数及边数
        printf("
    请输入城市数据:	");
        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("
    请输入存在路线的两个城市以及票价(比如:2,3,4):	");
            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)
    ");
                scanf("%d,%d", &from, &to);
                result = Floyd(S, from, to);
                printf("最低花费是  %d 
    ", result);
                break;
            case 3:
                printf(" 再见!
    ");
                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:   再见!
    
  • 相关阅读:
    证券市场主体
    证券投资基金
    1.监控系统的重要性
    1.五种世界顶级思维-20190303
    【四校联考】【比赛题解】FJ NOIP 四校联考 2017 Round 7
    【学长出题】【比赛题解】17-09-29
    【codeforces】【比赛题解】#854 CF Round #433 (Div.2)
    【codeforces】【比赛题解】#851 CF Round #432 (Div.2)
    【算法学习】三分法
    【codeforces】【比赛题解】#849 CF Round #431 (Div.2)
  • 原文地址:https://www.cnblogs.com/desola/p/12943347.html
Copyright © 2011-2022 走看看