Book 最短路算法

用HDU2544整理一下最近学的最短路算法

1.Dijkstra算法

原理:集合S表示已经找到最短路径的点,d[]表示当前各点到源点的距离

初始时,集合里面只有源点,当每个点u进入集合S时,用d[u]+w[u][v]更新距离

再重复这个步骤,选取S外所有点中d[]最小的进入集合

直到所有的点都进入S集合

局限性:图的边权必须为正

复杂度:O(V*V),堆优化((E+V)logV)

(1)用邻接矩阵实现

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include <cmath>
 5 #include<stack>
 6 #include<vector>
 7 #include<map>
 8 #include<set>
 9 #include<queue>
10 #include<algorithm>
11 using namespace std;
12
13 typedef long long LL;
14 const int INF = (1<<30)-1;
15 const int mod=1000000007;
16 const int maxn=10005;
17 int w[maxn][maxn],d[maxn],used[maxn];
18 int n,m;
19
20 void dijkstra(int s){
21     memset(used,0,sizeof(used));
22     for(int i=1;i<=n;i++) d[i]=INF;
23     d[s]=0;
24
25     for(int k=1;k<=n;k++){
26         int p,m=INF;
27         for(int i=1;i<=n;i++) if(!used[i]&&d[i]<m) m=d[p=i];
28         used[p]=1;
29         for(int i=1;i<=n;i++) d[i]=min(d[i],d[p]+w[p][i]);
30     }
31 }
32
33 int main(){
34     int a,b,c;
35     while(scanf("%d %d",&n,&m)!=EOF&&n&&m){
36         for(int i=1;i<=n;i++){
37             for(int j=1;j<=n;j++){
38                 if(i==j) w[i][j]=0;
39                 else w[i][j]=INF;
40             }
41         }
42
43         for(int i=1;i<=m;i++){
44             scanf("%d %d %d",&a,&b,&c);
45             w[a][b]=w[b][a]=c;
46         }
47         dijkstra(1);
48         printf("%d\n",d[n]);

49     }
50     return 0;
51 }

(2)用邻接表实现

注意记得每次调用dijkstra()时,first[]置为-1

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include <cmath>
 5 #include<stack>
 6 #include<vector>
 7 #include<map>
 8 #include<set>
 9 #include<queue>
10 #include<algorithm>
11 using namespace std;
12
13 typedef long long LL;
14 const int INF = (1<<30)-1;
15 const int mod=1000000007;
16 const int maxn=10005;
17 int d[maxn],used[maxn],firstt[maxn],nextt[maxn];
18 int n,m,ecnt;
19
20 struct edge{
21     int v,cost;
22 } e[maxn];
23
24 void dijkstra(int s){
25     memset(used,0,sizeof(used));
26     for(int i=1;i<=n;i++) d[i]=INF;
27     d[s]=0;
28
29     for(int k=1;k<=n;k++){
30         int p,m=INF;
31         for(int i=1;i<=n;i++) if(!used[i]&&d[i]<m) m=d[p=i];
32         used[p]=1;
33         for(int i=firstt[p];i!=-1;i=nextt[i]){
34             int v=e[i].v;
35             if(d[v]>d[p]+e[i].cost)
36             d[v]=d[p]+e[i].cost;
37         }
38     }
39 }
40
41 void addedges(int u,int v,int w){
42     nextt[++ecnt]=firstt[u];
43     e[ecnt].v=v;
44     e[ecnt].cost=w;
45     firstt[u]=ecnt;
46 }
47
48 int main(){
49     int a,b,c;
50     while(scanf("%d %d",&n,&m)!=EOF&&n&&m){
51         ecnt=0;
52         memset(firstt,-1,sizeof(firstt));
53
54         for(int i=1;i<=m;i++){
55             scanf("%d %d %d",&a,&b,&c);
56             addedges(a,b,c);
57             addedges(b,a,c);
58         }
59         dijkstra(1);
60         printf("%d\n",d[n]);
61     }
62     return 0;
63 }

时间: 2024-08-16 05:51:52

Book 最短路算法的相关文章

【啊哈!算法】算法7:Dijkstra最短路算法

上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”.例如求下图中的1号顶点到2.3.4.5.6号顶点的最短路径. <ignore_js_op> 与Floyd-Warshall算法一样这里仍然使用二维数组e来存储顶点之间边的关系,初始值如下. <ignore_js_op> 我们还需要用一个一维数组dis来存储1号顶点到其余各个顶点的初始路程,如下.

最短路算法汇总

校赛完了,这次校赛,做的很差,一个算法题没有,2个水题,1个贪心,概率DP,DP,数论题.DP还没开始研究,数论根本不会,数学太差了,省赛时卡数论,校赛依然卡数论,我擦,还是得继续学习啊! 一把锈迹斑斑的剑,只有不断的磨砺,才能展露锋芒! 以下为最短路总结: 最短路问题可分为: 一.单源最短路径算法,解决方案:Bellman-Ford算法,Dijkstra算法,SPFA 二.每对顶点间的最短路径算法:Floyd: (1).Dijkstra算法: (经典的算法,可以说是最短路问题的首选事例算法,但

最短路算法及其延伸

个人算法训练题集:http://acm.hust.edu.cn/vjudge/contest/toListContest.action#contestType=0&contestRunningStatus=0&contestOpenness=0&title=风斩冰华&manager= 密码xwd,欢迎大家一起来学习. 首先复习一下最短路问题,即求某两点之间边权最小的一条路径.这样就延伸出了两个子问题: 求任意两点的距离,还是求图上固定一个起点到某点的距离? 验题:http:

【啊哈!算法】算法6:只有五行的Floyd最短路算法

暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有4个城市8条公路,公路上的数字表示这条公路的长短.请注意这些公路是单向的.我们现在需要求任意两个城市之间的最短路程,也就是求任意两个点之间的最短路径.这个问题这也被称为“多源最短路径”问题. 现在需要一个数据结构来存储图的信息,我们仍然可以用一个4*4的矩阵(二维数组e)来存储.比如1号城市到2号城市的路程为2,则设e[1][2]

最短路算法大杂烩

最短路算法主要有以下几个: 一 Dijkstra 二 Bellman-Ford 三 SPFA 四 ASP 五 Floyd-Warshall 首先约定一下图的表示: struct Edge{         int from,to,wt;     };     vector<int>G[N];     vector<Edge>G[N]; -------------Dijkstra算法 使用条件:无负权边 复杂度O:((V+E)*log(V)) 下面是用优先队列实现的Dijkstra算

近十年one-to-one最短路算法研究整理【转】

前言:针对单源最短路算法,目前最经典的思路即标号算法,以Dijkstra算法和Bellman-Ford算法为根本演进了各种优化技术和算法.针对复杂网络,传统的优化思路是在数据结构和双向搜索上做文章,或者针对不必要的循环进行排除.近年来,最短路算法大量应用于需要高及时性的领域,比如GIS领域,也大量应用于网络规模巨大的社会网络分析领域,这使得传统思路并不能很好地解决,于是把最短路算法思路本身抽象成两阶段算法,第一阶段为数据预处理,第二阶段为实时地搜索.这二者是互相矛盾的,如何找到平衡是各种算法技术

dijkstra(迪杰斯特拉)最短路算法的堆优化

dijkstra(迪杰斯特拉)最短路算法是一种时间复杂度经过严格证明的最短路算法. 优化在于每次取最小值的时候采用堆优化,但是在最短路松弛过程中,dist是不断修改的,所以,为了能使复杂度降到O(nlogn),dist修改的同时,在堆中也要修改. 注意dijkstra(迪杰斯特拉)最短路算法只能用于正权边. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algo

hdu 4568 spfa 最短路算法+旅行商问题

http://acm.hdu.edu.cn/showproblem.php?pid=4568 Problem Description One day, a hunter named James went to a mysterious area to find the treasures. James wanted to research the area and brought all treasures that he could. The area can be represented a

最短路算法 :Bellman-ford算法 &amp; Dijkstra算法 &amp; floyd算法 &amp; SPFA算法 详解

 本人QQ :2319411771   邮箱 : [email protected] 若您发现本文有什么错误,请联系我,我会及时改正的,谢谢您的合作! 本文为原创文章,转载请注明出处 本文链接   :http://www.cnblogs.com/Yan-C/p/3916281.html . 很早就想写一下最短路的总结了,但是一直懒,就没有写,这几天又在看最短路,岁没什么长进,但还是加深了点理解. 于是就想写一个大点的总结,要写一个全的. 在本文中因为邻接表在比赛中不如前向星好写,而且前向星效率并