7-9 旅游规划(25 分)(Dijkstra最短路径算法)
有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。
输入格式:
输入说明:输入数据的第1行给出4个正整数N、M、S、D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N−1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。
输出格式:
在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。
输入样例:
4 5 0 3
0 1 1 20
1 3 2 30
0 3 4 10
0 2 2 20
2 3 1 20
输出样例:
3 40
解题思路:1、很明显这是一个图的问题,但是它有两个权值,因而我用了一个三元数组来存储数据
2、又因其是单源最短路径,因而使用Dijkstra算法
3、其次注意一下如果最短距离相同还要判断费用是否最小
4、最后还要小心0也算是一个城市
#include<stdio.h>
#include<stdlib.h> #define MAXVEX 505
#define INFINITY 65535 void CreateGraph( );
void Dijkstra( int v); int G[MAXVEX][MAXVEX][],Nv,Ne;
int know[MAXVEX]; //know[]=1表示求得最短路径
int distance[MAXVEX]; //表示求的最短距离
int pay[MAXVEX]; //表示最少费用
//int P[MAXVEX]; //存储最短路径的下标 int main()
{
int s,d;
scanf("%d %d %d %d",&Nv,&Ne,&s,&d);
CreateGraph();
Dijkstra(s);
if( distance[d]<INFINITY ){
printf("%d %d",distance[d],pay[d]);
} return ;
} void CreateGraph()
{
//用邻接矩阵表示图
int i,j;
int v1,v2;
int dn,f; //dn表示距离,f表示费用 for( i=; i<Nv; i++)
{
for( j=; j<Nv; j++)
{
G[i][j][] = INFINITY; //初始化
G[i][j][] = INFINITY;
}
} for( i=; i<Ne; i++) //注意这里是读入边
{
scanf("%d %d %d %d",&v1,&v2,&dn,&f);
G[v1][v2][] = G[v2][v1][]=dn;
G[v1][v2][] = G[v2][v1][]=f;
}
} void Dijkstra( int v)
{
//求从v结点到其他各结点的最短距离
int i,j,k;
int min,cost; for( i=; i<Nv; i++)
{
know[i] =;
distance[i] =G[v][i][]; //将与v点有连接的结点加上距离
pay[i] =G[v][i][];
} know[v] = ;
distance[v] =; //V到V距离为0
pay[v] = ; for( i=; i<Nv; i++)
{
min = INFINITY; //当前所知离v结点的最近距离
for( j=; j<Nv; j++)
{
//寻找离v结点的最近距离
if( !know[j] && distance[j]<min)
{
k = j;
min = distance[j];
cost = pay[j];
}
} know[k] = ;
for( j=; j<Nv; j++)
{
//修正最短路径和距离
if( !know[j] && (min+G[k][j][]<distance[j]))
{
distance[j] = min+G[k][j][];
pay[j] = cost + G[k][j][]; }
else if( !know[j] && (min+G[k][j][]==distance[j]) && (cost+G[k][j][] < pay[j]))
{ pay[j] = cost + G[k][j][];
}
} } }
以上是用邻接矩阵存储的,还有一种方法是使用邻接表来实现,以下是用C++写的,个人感觉更容易理解一些,空间复杂度也小一些
#include<stdio.h>
#include<queue>
#include<vector>
using namespace std; struct E
{
int next;
int cost;
int dis;
};
vector<E> edge[];
bool mark[];
int dis[];
int cost[]; int main()
{
int n,m,S,T; //起点终点
int i,j;
E temp;
int newP;
while( scanf("%d%d%d%d",&n,&m,&S,&T)!=EOF)
{
if( n== && m==) break; for( i=; i<=n; i++)
{
edge[i].clear(); //初始化邻接链表
dis[i] = -;
mark[i] = false;
cost[i] = ;
}
while( m--)
{
int a,b,d,c;
scanf("%d%d%d%d",&a,&b,&d,&c);
temp.cost = c;
temp.next = b;
temp.dis = d;
edge[a].push_back(temp);
temp.next = a;
edge[b].push_back(temp); //无向图,故每条边信息都要添加到两个顶点的单链表中
} dis[S] = ;
mark[S] = ;
newP = S; //起点为s
for( i=; i<n; i++)
{
for( j=; j<edge[newP].size(); j++)
{
//更新一个顶点对它的边表内结点的距离
int next = edge[newP][j].next;
int c = edge[newP][j].cost;
int d = edge[newP][j].dis;
if( mark[next]==true) continue;
if( dis[next]==- || dis[next]>dis[newP]+d
|| ((dis[next]==dis[newP]+d) &&(cost[next]>cost[newP]+c)))
{
dis[next] = dis[newP]+d;
cost[next] = cost[newP]+c;
}
}
int minx = ;
for( j=; j<=n; j++)
{
//寻找这个顶点出发的最小值
if( mark[j]==true) continue;
if( dis[j]==-) continue;
if( dis[j]<minx)
{
minx = dis[j];
newP = j;
}
}
mark[newP] = true;
}
printf("%d %d\n",dis[T],cost[T]);
}
return ;
}
7-9 旅游规划(25 分)(Dijkstra最短路径算法)的更多相关文章
- PTA 07-图6 旅游规划 (25分)
题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/717 5-9 旅游规划 (25分) 有了一张自驾旅游路线图,你会知道城市间的高速公路 ...
- 【(图) 旅游规划 (25 分)】【Dijkstra算法】
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> us ...
- PAT 07-图6 旅游规划 (25分)
有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路径都是最短的,那么需要输出最便 ...
- Java邻接表表示加权有向图,附dijkstra最短路径算法
从A到B,有多条路线,要找出最短路线,应该用哪种数据结构来存储这些数据. 这不是显然的考查图论的相关知识了么, 1.图的两种表示方式: 邻接矩阵:二维数组搞定. 邻接表:Map<Vertext, ...
- 数据结构(c++)(第二版) Dijkstra最短路径算法 教学示范代码出现重大问题!
前言 去年在数据结构(c++)的Dijkstra教学算法案例中,发现了一个 bug 导致算法不能正常的运行,出错代码只是4行的for循环迭代代码. 看到那里就觉得有问题,但书中只给了关键代码的部分,其 ...
- 练习 Dijkstra 最短路径算法。
练习 Dijkstra 最短路径算法. #coding: utf-8 # Author: woodfox, Oct 14, 2014 # http://en.wikipedia.org/wiki/Di ...
- 1003 Emergency (25分) 求最短路径的数量
1003 Emergency (25分) As an emergency rescue team leader of a city, you are given a special map of ...
- 一篇文章讲透Dijkstra最短路径算法
Dijkstra是典型最短路径算法,计算一个起始节点到路径中其他所有节点的最短路径的算法和思想.在一些专业课程中如数据结构,图论,运筹学等都有介绍.其思想是一种基础的求最短路径的算法,通过基础思想的变 ...
- Dijkstra最短路径算法[贪心]
Dijkstra算法的标记和结构与prim算法的用法十分相似.它们两者都会从余下顶点的优先队列中选择下一个顶点来构造一颗扩展树.但千万不要把它们混淆了.它们解决的是不同的问题,因此,所操作的优先级也是 ...
- Python 图_系列之纵横对比 Bellman-Ford 和 Dijkstra 最短路径算法
1. 前言 因无向.无加权图的任意顶点之间的最短路径由顶点之间的边数决定,可以直接使用原始定义的广度优先搜索算法查找. 但是,无论是有向.还是无向,只要是加权图,最短路径长度的定义是:起点到终点之间所 ...
随机推荐
- 贪心 CodeForces 124B Permutations
题目传送门 /* 贪心:全排列函数使用,更新最值 */ #include <cstdio> #include <algorithm> #include <cstring& ...
- 员工管理系统(集合与IO流的结合使用 beta5.0 BufferedReader/ BufferedWriter)
package cn.gee; public class Emp { private String id;//员工编号 一般是唯一的 private String sname; private int ...
- 转 Docker和hadoop
2017-06-21 朱洁 Docker很热,怎么形容?感觉开源除了spark技术,就是docker了,甚至把Go语言也带火了,把Go在TIOBE的排名从百名外带入主流语言的行列. Docker快成救 ...
- D. Chloe and pleasant prizes 树上dp + dfs
http://codeforces.com/contest/743/problem/D 如果我们知道mx[1]表示以1为根节点的子树中,点权值的最大和是多少(可能是整颗树,就是包括了自己).那么,就可 ...
- [转]Azure 表存储和 Windows Azure SQL Database - 比较与对照
本文转自:https://msdn.microsoft.com/library/azure/jj553018 更新时间: 2014年10月 作者:Valery Mizonov 和 Seth Manhe ...
- js ajax 数组类型参数传递
若一个请求中包含多个值,如:(test.action?tid=1&tid=2&tid=3),参数都是同一个,只是指定多个值,这样请求时后台会发生解析错误,应先使用 tradititon ...
- TinyMCE编辑器
TinyMCE编辑器下载地址 http://www.tinymce.com/download/download.php
- Android一句代码给Activity定制标题栏
在此之前,使用过几种方法设置标题栏: 1.常规法:这个方法是最常用的了,哪个activity需要什么样的标题栏,就在对应的xml布局设计.缺点:此方法维护起来困难,没有将标题栏的共性抽取出来, 如果要 ...
- C#方法参数关键字
一.params关键字 prams告诉函数的调用者,该函数的参数数量是可变,如果调用函数的参数标识了params关键字,那么我们可以使用逗号分割的参数或者一个数组来作为参数: 1.这里只能是数组,Li ...
- 文档兼容性定义,使ie按指定的版本解析
作为开发人员,特别是作为Web的前端开发人员 ,最悲催的莫过于要不断的,不断的去调试各种浏览器的显示效果,而这其中最让人头痛的莫过于MS下的IE系列浏览器,在IE系列中的调试我们将会发现没有一个是好伺 ...