数据结构实战(五)——行车路线

本文介绍了一个关于图论和动态规划的问题,即如何规划行车路线以使司机小明的疲劳度最小。通过Floyd算法计算只走小道的情况,SPFA算法寻找起点到各点的最小距离。使用dis和dis0数组记录不同前一条边情况下的距离,并通过DFS找出最小疲劳度路径。最后,强调了算法选择的灵活性和重要性。
摘要由CSDN通过智能技术生成

任务简述
小明和小芳出去乡村玩,小明负责开车,小芳来导航。
  小芳将可能的道路分为大道和小道。大道比较好走,每走1公里小明会增加1的疲劳度。小道不好走,如果连续走小道,小明的疲劳值会快速增加,连续走s公里小明会增加s2的疲劳度。
  例如:有5个路口,1号路口到2号路口为小道,2号路口到3号路口为小道,3号路口到4号路口为大道,4号路口到5号路口为小道,相邻路口之间的距离都是2公里。如果小明从1号路口到5号路口,则总疲劳值为(2+2)2+2+22=16+2+4=22。
现在小芳拿到了地图,请帮助她规划一个开车的路线,使得按这个路线开车小明的疲劳度最小。
[基本要求]
输入格式:
  输入的第一行包含两个整数n, m,分别表示路口的数量和道路的数量。路口由1至n编号,小明需要开车从1号路口到n号路口。
接下来m行描述道路,每行包含四个整数t, a, b, c,表示一条类型为t,连接a与b两个路口,长度为c公里的双向道路。其中t为0表示大道,t为1表示小道。保证1号路口和n号路口是连通的。
输出格式
输出一个整数,表示最优路线下小明的疲劳度。
样例输入
6 7
1 1 2 3
1 2 3 2
0 1 3 30
0 3 4 20
0 4 5 30
1 3 5 6
1 5 6 1
样例输出
76
样例说明
  从1走小道到2,再走小道到3,疲劳度为52=25;然后从3走大道经过4到达5,疲劳度为20+30=50;最后从5走小道到6,疲劳度为1。总共为76。
课程设计要求:
(1)要求从文本文件中输入;
(2)采用适当的数据结构存储由输入数据中的道路所形成的图结构;
(3)编写尽可能优的算法,处理好连续走小道造成的疲劳值的指数增长(提示:基于迪杰斯特拉算法进行改进即可完成本题);
(4)除严格按题目要求进行输出以外,还要求输出最优路线的路径,以及从出发点到各个点的最小疲劳值。

2、算法描述:
先用floyd算法求出每个点间只走小道的情况下的距离,然后用spfa算法求起点到各点的最小距离。用dis数组和dis0数组来存放起点到每个点的距离,dis数组是前一条边是大道的路,dis0数组是前一条边是小道的路。对每次出队的点k,都用其对图中每个点进行一次松弛操作。由于总体的最短路径在局部也一定是最短的,所以考虑k到i的小道距离的时候只要考虑dis[k]即可。最后用dfs找出所有路径,输出疲劳值为最小值的路径。

源代码

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define maxx 999

typedef struct MyGraph//用邻接矩阵来表示 
{
   
	int type;//0,表示无向网,1表示有向网
	int arcnum,vexnum;
	int **A;//大道邻接矩阵 
	int **B;//小道邻接矩阵 
}GH;

void creatgraph(GH *G);//以邻接矩阵的形式创建图
void showgraph(GH *G);//以邻接矩阵的形式显示图
void spfa(GH *G,int start,int end,int n);
void allpath(GH *G,int i,int j,int *path,int n,int *visit,int sum,int v,int nowdis);

int main()
{
   
	int start,end;
	GH G;
	creatgraph(&G);//创建并展示图
	printf("输入起点和终点:\n");
	scanf("%d %d",&start,&end); 
	spfa(&G,start-1,end-1,G.vexnum);
	return 0;
}

void creatgraph(GH *G){
   //创建图 
	FILE *fp;
	int i,j,k,m,n,t,a,b,c;
	fp=fopen("kkk.txt","rb");
	if(fp==NULL){
   
		printf("can not open file\n");
		exit(0);
	}
	fscanf(fp,"%d %d",&n,&m);
	G->vexnum=n;
	G->arcnum=m;
	G->type=0;
	G->B=(int **)malloc(n*sizeof(int *));
	G->A=(int **)malloc(n*sizeof(int *));
	for(i=0;i<n;i++){
   
		G->A[i]=(int *)
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值