有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。

输入格式:

输入说明:输入数据的第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最短路径算法)的更多相关文章

  1. PTA 07-图6 旅游规划 (25分)

    题目地址 https://pta.patest.cn/pta/test/15/exam/4/question/717 5-9 旅游规划   (25分) 有了一张自驾旅游路线图,你会知道城市间的高速公路 ...

  2. 【(图) 旅游规划 (25 分)】【Dijkstra算法】

    #include<iostream> #include<cstdio> #include<algorithm> #include<cstring> us ...

  3. PAT 07-图6 旅游规划 (25分)

    有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路径都是最短的,那么需要输出最便 ...

  4. Java邻接表表示加权有向图,附dijkstra最短路径算法

    从A到B,有多条路线,要找出最短路线,应该用哪种数据结构来存储这些数据. 这不是显然的考查图论的相关知识了么, 1.图的两种表示方式: 邻接矩阵:二维数组搞定. 邻接表:Map<Vertext, ...

  5. 数据结构(c++)(第二版) Dijkstra最短路径算法 教学示范代码出现重大问题!

    前言 去年在数据结构(c++)的Dijkstra教学算法案例中,发现了一个 bug 导致算法不能正常的运行,出错代码只是4行的for循环迭代代码. 看到那里就觉得有问题,但书中只给了关键代码的部分,其 ...

  6. 练习 Dijkstra 最短路径算法。

    练习 Dijkstra 最短路径算法. #coding: utf-8 # Author: woodfox, Oct 14, 2014 # http://en.wikipedia.org/wiki/Di ...

  7. 1003 Emergency (25分) 求最短路径的数量

    1003 Emergency (25分)   As an emergency rescue team leader of a city, you are given a special map of ...

  8. 一篇文章讲透Dijkstra最短路径算法

    Dijkstra是典型最短路径算法,计算一个起始节点到路径中其他所有节点的最短路径的算法和思想.在一些专业课程中如数据结构,图论,运筹学等都有介绍.其思想是一种基础的求最短路径的算法,通过基础思想的变 ...

  9. Dijkstra最短路径算法[贪心]

    Dijkstra算法的标记和结构与prim算法的用法十分相似.它们两者都会从余下顶点的优先队列中选择下一个顶点来构造一颗扩展树.但千万不要把它们混淆了.它们解决的是不同的问题,因此,所操作的优先级也是 ...

  10. Python 图_系列之纵横对比 Bellman-Ford 和 Dijkstra 最短路径算法

    1. 前言 因无向.无加权图的任意顶点之间的最短路径由顶点之间的边数决定,可以直接使用原始定义的广度优先搜索算法查找. 但是,无论是有向.还是无向,只要是加权图,最短路径长度的定义是:起点到终点之间所 ...

随机推荐

  1. BZOJ 1396||2865 识别子串

    这个不是题解,看不懂的,别看了 明明应该是会的,怎么还是写了6个小时呢... 把后缀数组.height数组.排名数组求出来,那么对于原串s的任意子串[x,y](表示第x个到第y个字符组成的子串,字符从 ...

  2. D. Dasha and Very Difficult Problem 二分

    http://codeforces.com/contest/761/problem/D c[i] = b[i] - a[i],而且b[]和a[]都属于[L, R] 现在给出a[i]原数组和c[i]的相 ...

  3. Android开发学习—— 消息机制

    ###主线程不能被阻塞* 在Android中,主线程被阻塞会导致应用不能刷新ui界面,不能响应用户操作,用户体验将非常差* 主线程阻塞时间过长,系统会抛出ANR异常* ANR:Application ...

  4. AngularJS入门 & 分页 & CRUD示例

    一.AngularJS 简介 ​ AngularJS  诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用于Google的多款产品当中. ...

  5. [BZOJ1878][SDOI2009]HH的项链 莫队

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1878 不带修改的莫队,用一个桶记录一下当前区间中每种颜色的数量就可以做到$O(1)$更新了 ...

  6. VUE 全选

    <div id="vue_det"> <p>全选:</p> <input type="checkbox" id=&qu ...

  7. BootStrap Select2组件

    想使用Select2组件必须引用:select2.min.css和select2.min.js两个文件:如下: 页面写法很简单: 在这里多选是没有搜索功能的,只有单选的时候才会有搜索功能. Selec ...

  8. css选择器的对比样式代码精简

    通常就分为这三大类:* 选定所有对象.通配选择符(Universal Selector)通常不建议使用通配选择符,因为它会遍历并命中文档中所有的元素,出于性能考虑,需酌情使用一.标签选择器,以开始标签 ...

  9. IE和DOM事件流、普通事件和绑定事件的区别

    IE和DOM事件流的区别 IE采用冒泡型事件 Netscape(网络信息浏览器)使用捕获型事件 DOM使用先捕获后冒泡型事件 示例: <body> <div> <butt ...

  10. 什么是混合app开发

    webApp 移动app 就是在浏览器中运行的web应用 (网页应用)开发成本低 体验差 不需要安装 NativeApp :用Android和object-C原生语言开发的应用 开发成本高 需要安装( ...