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

输入格式:

输入说明:输入数据的第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. 递推DP UVA 1291 Dance Dance Revolution

    题目传送门 题意:给一串跳舞的动作,至少一只脚落到指定的位置,不同的走法有不同的体力消耗,问最小体力消费多少分析:dp[i][j][k] 表示前i个动作,当前状态(j, k)的最小消费,状态转移方程: ...

  2. electron打包整理

    最近在折腾把项目打包成桌面应用程序,发现一个工具electron,可以讲项目打包成一个跨平台的应用程序,很方便,来学习一下. 1.先安装electron.electron-packager,安装方法可 ...

  3. jmeter(二)元件的作用域与执行顺序

    1.元件的作用域 JMeter中共有8类可被执行的元件(测试计划与线程组不属于元件),这些元件中,取样器是典型的不与其它元件发生交互作用的元件,逻辑控制器只对其子节点的取样器有效,而其它元件(conf ...

  4. poj3735Training little cats

    链接 构造矩阵 快速幂求解 构造矩阵a[i]为每个cati所拥有的花生总数 这里多加一维用来求和,具体是怎么求得可以看下面的一组例子 假设有3个cat a[] = {1,0,0,0} 构造单位矩阵来保 ...

  5. SQL Server 编程入门

    一.T—SQL 的组成 1.DML(数据操作语言 Data Manipulation Language) 查询.插入.删除和修改数据库中的数据.SELECT.INSERT.UPDATE.DELETE ...

  6. WCF中的异步实现

    对于WCF中通讯的双方来说,客户端可以异步的调用服务:服务端对服务也能以异步的方式实现. 目录: 1.WCF客户端异步调用服务 2.服务端的异步实现 WCF客户端异步调用服务主要通过生成异步的代理类, ...

  7. AlertDialog的实现

    课程Demo 重点解析自定义对话框 public class MainActivity extends AppCompatActivity { private Button bt1; private ...

  8. SDK manager.exe 运行时报错:系统找不到指定的文件 android.bat

    android studio 2.3.1的 SDK Manager工具 突然没有 Launcher XXX 那个按钮,只好到SDK目录中去启动,无奈发生以下错误. 解决办法:运行android.bat ...

  9. 使用Jenkins进行android项目的自动构建(2)

    Maven and POM 1. 什么是Maven? 官方的解释是: http://maven.apache.org/guides/getting-started/index.html#What_is ...

  10. SQL Server中行列转置方法

    PIVOT用于将列值旋转为列名(即行转列),在SQL Server 2000可以用聚合函数配合CASE语句实现 PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P ...