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

输入格式:

输入说明:输入数据的第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. 424 Longest Repeating Character Replacement 替换后的最长重复字符

    给你一个仅由大写英文字母组成的字符串,你可以将任意位置上的字符替换成另外的字符,总共可最多替换 k 次.在执行上述操作后,找到包含重复字母的最长子串的长度.注意:字符串长度 和 k 不会超过 104. ...

  2. LN : leetcode 123 Best Time to Buy and Sell Stock III

    lc 123 Best Time to Buy and Sell Stock III 123 Best Time to Buy and Sell Stock III Say you have an a ...

  3. BootStrap Select2组件

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

  4. Farseer.net轻量级ORM开源框架 V1.8版本升级消息

    SHA-1: 775a93cf64df3f49c83cc4f4df346afd2075a68f * 发布V1.8.0修复:Oracle的SQL生成 在没有条件时,缺少Where关键字,导致无法分页修复 ...

  5. 经典算法mark

    在平时找工作的时候,或多或少会遇到一些算法问题,很多都是比较经典或者网上已经流传很久的.只是我们没有接触过,所以不知道怎么解决. 在这儿,我自己总结一些我遇到的一些经典算法,给自己增加一点记忆,也给需 ...

  6. ubuntu 下安装redis

    获取Redis 1.通过官网http://redis.io/获取稳定版源码包下载地址: 2.通过wget http://download.redis.io/releases/redis-3.0.2.t ...

  7. C++模版完全解析

    模版 模版在C++中是一个很重要的概练,生活中的模版也是随处可见,比如制造工程师会 哪一个模子去构造出一个一个的工件,C++程序员能够用模版去实例化y有相同操作 不同类型的函数或者数据结构.简单的理解 ...

  8. ALTER LANGUAGE - 修改一个过程语言的定义

    SYNOPSIS ALTER LANGUAGE name RENAME TO newname DESCRIPTION 描述 ALTER LANGUAGE 修改一门语言的定义. 目前唯一的功能就是重命名 ...

  9. winpcap编程设置过滤器之指定获取某个网站的数据

    下面,我将以 乱世隋唐页游 为例,通过编码获取这里面的数据. 游戏图: 我是乱世隋唐的网址是:www.917st.com 这个是官网网址的服务器地址.  42.62.0.14 我玩的游戏服是84区.网 ...

  10. 08CSS边框边距

    CSS边框边距 边框样式——border-style border-top-style border-bottom-style border-left-style border-right-style ...