博客
关于我
最短路 dijkstra 学习、代码实现
阅读量:395 次
发布时间:2019-03-05

本文共 3404 字,大约阅读时间需要 11 分钟。

1. 概述

dijkstra 单源最短路, 单源最短路即把一个点当作源点,求得这个点到其它点的最短路。

算法的基本思路:

首先用一个辅助数组 pos[ ], pos[i] 就是源点到 结点 i 的最短距离,如果邻接矩阵存储,pos[ ] 也就是 a[i][ ]。一个标记数组vis[], vis[i] 为 true 则已经找到源点到这个点的最短距离,为false则还未确定源点到这个点的最短距离,假设源点编号为sta,vis[sta] 初始为true ,因为源点到源点距离肯定为 0。

(1)从pos[ ]中找到离未标记且距离源点最近(即pos[]值最小)的一个点,标记这个节点,然后用这个点去更新pos[] 中的其他结点 。

例如:pos[3]未标记且pos[3] 最小,那么pos[3] 就是源点到结点3的最短距离,标记这个节点,然后用这个点去更新其他 pos[] 中节点,这里的更新指的是源点通过节点3到达其他节点的距离,距离小于当前的辅助数组中的值则更新,否则不更新辅助数组。

(2)更新 n-1 次之后(假设源点可达所有节点),pos[] 中即源点到达其他节点的最短路。

2.  代码实现

// 最短路 dijkstra// 时间复杂度:n^2, n 为 节点数#include 
#include
const int INF = 1000000007;const int N = 1010;// 存储图, a[i][j] 是节点 i 到 节点 j 的 距离int a[N][N];// point[i].vis = 1 已经找到 起始点 到 节点i 的最短距离// point[i].vis = 0 还没有找到 起始点 到 节点i 的最短距离// point[i].dis, 起始点 到 节点i 的最短距离typedef struct point { int vis, dis;}P;P pos[N];// 节点总数为 n, 节点编号从 1 开始, sta 为起始点编号void Dijkstra(int n, int sta) { // 初始化 pos[N] for(int i=1; i<=n; i++) { pos[i].vis = 0; pos[i].dis = a[sta][i]; } pos[sta].vis = 1, pos[sta].dis = 0; for(int i=2; i<=n; i++) { // minDist 起始点到未找到最短距离的节点的最短距离 // minj 存储每一次找到节点的 编号 int minDist = INF, minj = -1; // 寻找起始点到未找到最短距离的节点的最短距离 for(int j=1; j<=n; j++) { if(0==pos[j].vis && pos[j].dis

3.  代码验证:poj  1062   昂贵的聘礼

       题目传送:

                                                                                       昂贵的聘礼

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 51393   Accepted: 15384

Description

年轻的探险家来到了一个印第安部落里。在那里他和酋长的女儿相爱了,于是便向酋长去求亲。酋长要他用10000个金币作为聘礼才答应把女儿嫁给他。探险家拿不出这么多金币,便请求酋长降低要求。酋长说:"嗯,如果你能够替我弄到大祭司的皮袄,我可以只要8000金币。如果你能够弄来他的水晶球,那么只要5000金币就行了。"探险家就跑到大祭司那里,向他要求皮袄或水晶球,大祭司要他用金币来换,或者替他弄来其他的东西,他可以降低价格。探险家于是又跑到其他地方,其他人也提出了类似的要求,或者直接用金币换,或者找到其他东西就可以降低价格。不过探险家没必要用多样东西去换一样东西,因为不会得到更低的价格。探险家现在很需要你的帮忙,让他用最少的金币娶到自己的心上人。另外他要告诉你的是,在这个部落里,等级观念十分森严。地位差距超过一定限制的两个人之间不会进行任何形式的直接接触,包括交易。他是一个外来人,所以可以不受这些限制。但是如果他和某个地位较低的人进行了交易,地位较高的的人不会再和他交易,他们认为这样等于是间接接触,反过来也一样。因此你需要在考虑所有的情况以后给他提供一个最好的方案。 

为了方便起见,我们把所有的物品从1开始进行编号,酋长的允诺也看作一个物品,并且编号总是1。每个物品都有对应的价格P,主人的地位等级L,以及一系列的替代品Ti和该替代品所对应的"优惠"Vi。如果两人地位等级差距超过了M,就不能"间接交易"。你必须根据这些数据来计算出探险家最少需要多少金币才能娶到酋长的女儿。 

Input

输入第一行是两个整数M,N(1 <= N <= 100),依次表示地位等级差距限制和物品的总数。接下来按照编号从小到大依次给出了N个物品的描述。每个物品的描述开头是三个非负整数P、L、X(X < N),依次表示该物品的价格、主人的地位等级和替代品总数。接下来X行每行包括两个整数T和V,分别表示替代品的编号和"优惠价格"。

Output

输出最少需要的金币数。

Sample Input

1 410000 3 22 80003 50001000 2 14 2003000 2 14 20050 2 0

Sample Output

5250

解题思路:

     把冒险者当作点1, 酋长往后的点依次后推, 求点1 到 点2 的最短距离, 把每一个人,都当成最高等级的,然后用 dijkstra去求, 不断更新最优解。

代码:

// poj 1062#include 
#include
const int INF = 1000000007;const int N = 1010;// 设置冒险者的编号为 1, 所有的物品编号从 2 开始// a[1][j] 冒险家购买 物品 j 所需金币// a[i][j] 使用物品 i 后 购买 物品 j 所需 金币数int a[N][N], level[N];typedef struct point { int vis, dis;}P;P pos[N];// 节点总数为 n, 节点编号从 1 开始, sta 为起始点编号void Dijkstra(int n, int sta) { // 初始化 pos[N] for(int i=1; i<=n; i++) { //pos[i].vis = 0; pos[i].dis = a[sta][i]; } pos[sta].vis = 1, pos[sta].dis = 0; for(int i=2; i<=n; i++) { // minDist 起始点到未找到最短距离的节点的最短距离 // minj 存储每一次找到节点的 编号 int minDist = INF, minj = -1; // 寻找起始点到未找到最短距离的节点的最短距离 for(int j=1; j<=n; j++) { if(0==pos[j].vis && pos[j].dis
m || level[i]>level[j]) { pos[j].vis = 1; } else { pos[j].vis = 0; } } Dijkstra(n+1, 1); if(pos[2].dis < ans) { ans = pos[2].dis; } } printf("%d\n", ans); return 0;}

 

转载地址:http://qdkzz.baihongyu.com/

你可能感兴趣的文章
MYSQL 主从同步文档的大坑
查看>>
mysql 主键重复则覆盖_数据库主键不能重复
查看>>
Mysql 事务知识点与优化建议
查看>>
Mysql 优化 or
查看>>
mysql 优化器 key_mysql – 选择*和查询优化器
查看>>
MySQL 优化:Explain 执行计划详解
查看>>
Mysql 会导致锁表的语法
查看>>
mysql 使用sql文件恢复数据库
查看>>
mysql 修改默认字符集为utf8
查看>>
Mysql 共享锁
查看>>
MySQL 内核深度优化
查看>>
mysql 内连接、自然连接、外连接的区别
查看>>
mysql 写入慢优化
查看>>
mysql 分组统计SQL语句
查看>>
Mysql 分页
查看>>
Mysql 分页语句 Limit原理
查看>>
MySql 创建函数 Error Code : 1418
查看>>
MySQL 创建新用户及授予权限的完整流程
查看>>
mysql 创建表,不能包含关键字values 以及 表id自增问题
查看>>
mysql 删除日志文件详解
查看>>