【数据结构课程设计】题目五:交通咨询系统设计(经典最短路问题)

题目五:交通咨询系统设计

设计要求:

设计一个咨询交通系统,能让旅客咨询从任一个城市到另一个城市之间的最短路径(里程)、最低费用或者最少时间等问题。对于不同的咨询要求,可以输入城市间路程、所需时间或者所需费用。

设计分3个部分:
1、 建立交通网络图的存储结构;
2、 解决单源最短路径问题;
3、 实现两个城市之间的最短路径问题。

在这里插入图片描述
1、直接用二维数组存放图的信息

注意图是有向图还是无向图

void build(int e[][10],int n,int m)
{
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			e[i][j]=(i==j)?0:inf;
			
	for(int i=1;i<=m;i++)
	{
		int t1,t2,d;//位置t1到位置t2的距离是d 
		cin>>t1>>t2>>d;
		e[t1][t2]=e[t2][t1]=d;//无向图 
	}
}

2、单源最短路Dijkstra算法

最近意识到经常因为阅读一些理论性的东西,导致实际学习效率变得非常低(因为常常理论性的文章不好读懂,且本人看一大段文章的时候容易走神)

现在越发觉得,很多关于算法的题目知识点什么的直接看代码,在做题中巩固实际上是效率很高的一种学习方法,所以我也不叨叨什么单源多源最短路的实现思想了

直接上代码,就是看着代码学,看着代码找感觉(当然稍微还是要明白一些背景知识的,不要死磕,知道大体什么意思,直接刚代码)

单源最短路:找出一个点到其他所有点的最短路

void Dijkstra(int e[][10],int n)//贪心思想
{
	int dis[10],book[10]; //所求结点到其他结点的最短路  记录当前结点是否已经判断过了
	//初始化单源最短数组dis,这里是1号顶点到其余各顶点的初始路径
	for(int i=1; i<=n; i++)
		dis[i]=e[1][i];

	for(int i=2; i<=n; i++)
		book[i]=0;//未知最短路顶点
	book[1]=1;

	//Dijkstra 算法核心语句
	for(int i=1; i<=n-1; i++) {
		int min=inf,t;
		for(int j=1; j<=n; j++)
			if(book[j]==0&&dis[j]<min) { //找出未判断结点中到1号结点(单源最短路起点)距离最小结点
				min=dis[j];
				t=j;
			}
		book[t]=1;//及时将选出的该结点标记为已判断过了
		for(int v=1; v<=n; v++) { //判断其他结点借助当前选出的结点,是否使得到1号结点的距离变短
			if(e[t][v]<inf) {
				if(dis[v]>dis[t]+e[t][v])
					dis[v]=dis[t]+e[t][v];//记录借助当前选出结点使得到1号结点更短路径的新距离
			}
		}
	}

	cout<<"所求城市单源最短路径为:"<<endl;
	for(int i=2; i<=n; i++)
		cout<<citys[1]<<"->"<<citys[i]<<": "<<dis[i]<<endl;
}

3、多源最短路Floyd算法

void Floyd(int e[][10],int n)//多源最短路
{
	for(int i=1; i<=n; i++)
		for(int j=1; j<=n; j++)
			for(int k=1; k<=n; k++)
				if(e[i][k]+e[k][j]<e[i][j])
					e[i][j]=e[i][k]+e[k][j];

	for(int i=1; i<=n; i++)
		cout<<"\t"<<citys[i];
	cout<<endl;
	for(int i=1; i<=n; i++) {
		cout<<citys[i];
		for(int j=1; j<=n; j++)
			printf("%8d",e[i][j]);
		cout<<endl;
	}
}

4、直接完整代码好了

#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
string citys[10]= {"0","北京","西安","郑州","徐州","成都","广州","上海"};
void build(int e[][10],int n,int m)
{
	for(int i=1; i<=n; i++)
		for(int j=1; j<=n; j++)
			e[i][j]=(i==j)?0:inf;

	for(int i=1; i<=m; i++) {
		int t1,t2,d;//位置t1到位置t2的距离是d
		cin>>t1>>t2>>d;
		e[t1][t2]=e[t2][t1]=d;//无向图
	}
}

void Floyd(int e[][10],int n)//多源最短路
{
	for(int i=1; i<=n; i++)
		for(int j=1; j<=n; j++)
			for(int k=1; k<=n; k++)
				if(e[i][k]+e[k][j]<e[i][j])
					e[i][j]=e[i][k]+e[k][j];

	for(int i=1; i<=n; i++)
		cout<<"\t"<<citys[i];
	cout<<endl;
	for(int i=1; i<=n; i++) {
		cout<<citys[i];
		for(int j=1; j<=n; j++)
			printf("%8d",e[i][j]);
		cout<<endl;
	}
}

void Dijkstra(int e[][10],int n)//贪心思想
{
	int dis[10],book[10]; //所求结点到其他结点的最短路  记录当前结点是否已经判断过了
	//初始化单源最短数组dis,这里是1号顶点到其余各顶点的初始路径
	for(int i=1; i<=n; i++)
		dis[i]=e[1][i];

	for(int i=2; i<=n; i++)
		book[i]=0;//未知最短路顶点
	book[1]=1;

	//Dijkstra 算法核心语句
	for(int i=1; i<=n-1; i++) {
		int min=inf,t;
		for(int j=1; j<=n; j++)
			if(book[j]==0&&dis[j]<min) { //找出未判断结点中到1号结点(单源最短路起点)距离最小结点
				min=dis[j];
				t=j;
			}
		book[t]=1;//及时将选出的该结点标记为已判断过了
		for(int v=1; v<=n; v++) { //判断其他结点借助当前选出的结点,是否使得到1号结点的距离变短
			if(e[t][v]<inf) {
				if(dis[v]>dis[t]+e[t][v])
					dis[v]=dis[t]+e[t][v];//记录借助当前选出结点使得到1号结点更短路径的新距离
			}
		}
	}

	cout<<"所求城市单源最短路径为:"<<endl;
	for(int i=2; i<=n; i++)
		cout<<citys[1]<<"->"<<citys[i]<<": "<<dis[i]<<endl;
}

void Inquiry(int e[][10],int n)
{
	int i;
	string t;
	cout<<"请输入你要查询的城市名:";
	cin>>t;
	for(i=1; i<=n; i++) {
		if(citys[i]==t)
			break;
	}
	if(i==n+1) {
		cout<<endl<<"所查城市不在交通网络图中"<<endl;
		return ;
	}
	cout<<endl<<"所求城市"<<citys[i]<<"单源最短路径为:"<<endl;
	for(int j=1; j<=n; j++) {
		if(i==j) continue;
		cout<<citys[i]<<"->"<<citys[j]<<": "<<e[i][j]<<endl;
	}

}
void menu()
{
	int e[10][10];
	int n,m;//顶点个数  边的个数
	cin>>n>>m;
	build(e,n,m);
	Floyd(e,n);
	Dijkstra(e,n);

	Inquiry(e,n);
	Inquiry(e,n);
}

int main()
{
	freopen("data.txt","r",stdin);
	menu();
	return 0;
}

附带的测试数据:

7 10
1 2 2553
1 3 695
1 4 704
2 3 511
2 5 812
3 4 349
3 6 1579
4 7 651
5 6 2368
6 7 1385

徐州
青岛

5、用邻接矩阵且用文件形式读入数据

#include	<stdio.h>
#include	<stdlib.h>

#define Vertex_NUM 50				// 最大顶点数
#define INF 32767					// 无穷大∞

//邻接矩阵的类型定义如下:
typedef struct {
    int no;						//顶点编号
    char info;					//顶点其他信息
} VertexType;					//顶点类型

typedef struct {
    VertexType vexs[Vertex_NUM];			//存放顶点信息
    int arcs[Vertex_NUM][Vertex_NUM];		//邻接矩阵的边数组
    int	vn, en;								//顶点数,边数
} MGraph;									//完整的图邻接矩阵类型

void readfromDisk(MGraph *G)
{
    // 从磁盘读取数据
    int	i, j, w;
    char ch = 'A';				// 任意值
    FILE *inp;
    inp = fopen("data.in", "r");

    if(inp <= 0) {
        printf("\ndata.in文件不存在!请创建data.in文件吧!\n");
        exit(0);
    }

    fseek(inp, 0, SEEK_SET);

    printf("\n你所给定的图G各弧的权值为:\n");
    while(ch != EOF) {
        fscanf(inp, "%d %d %d", &i, &j, &w);
        G->arcs[i][j] = w;
        printf("<%d %d %d>\n", i, j, w);
        ch = fgetc(inp);
    }

    fclose(inp);
}

MGraph *CreateMGraph()
{
    int i, j, w;
    MGraph *G;

    G = (MGraph *)malloc(sizeof(MGraph));	//建立图的存储结构

    printf("\n输入图G的顶点个数 N = ");
    scanf("%d", &G->vn);

    for(i = 1; i <= G->vn; i++) {
        G->vexs[i].no = i;
    }

    for(i = 1; i <= G->vn; i++)
        for(j = 1; j <= G->vn; j++)
            G->arcs[i][j] = INF;

    readfromDisk(G);

    printf("\n图的存储建立完毕!\n");
    return	G;
}

int main()
{
    MGraph *G;
    G = CreateMGraph();
    return 0;
}

ㄟ( ▔, ▔ )ㄏ

  • 36
    点赞
  • 304
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值