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

1.Dijkstra算法

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

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

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

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

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

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

(1)用邻接矩阵实现

 #include<iostream>
#include<cstdio>
#include<cstring>
#include <cmath>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
using namespace std; typedef long long LL;
const int INF = (<<)-;
const int mod=;
const int maxn=;
int w[maxn][maxn],d[maxn],used[maxn];
int n,m; void dijkstra(int s){
memset(used,,sizeof(used));
for(int i=;i<=n;i++) d[i]=INF;
d[s]=; for(int k=;k<=n;k++){
int p,m=INF;
for(int i=;i<=n;i++) if(!used[i]&&d[i]<m) m=d[p=i];
used[p]=;
for(int i=;i<=n;i++) d[i]=min(d[i],d[p]+w[p][i]);
}
} int main(){
int a,b,c;
while(scanf("%d %d",&n,&m)!=EOF&&n&&m){
for(int i=;i<=n;i++){
for(int j=;j<=n;j++){
if(i==j) w[i][j]=;
else w[i][j]=INF;
}
} for(int i=;i<=m;i++){
scanf("%d %d %d",&a,&b,&c);
w[a][b]=w[b][a]=c;
}
dijkstra();
printf("%d\n",d[n]); }
return ;
}

(2)用邻接表实现

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

 #include<iostream>
#include<cstdio>
#include<cstring>
#include <cmath>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
using namespace std; typedef long long LL;
const int INF = (<<)-;
const int mod=;
const int maxn=;
int d[maxn],used[maxn],firstt[maxn],nextt[maxn];
int n,m,ecnt; struct edge{
int v,cost;
} e[maxn]; void dijkstra(int s){
memset(used,,sizeof(used));
for(int i=;i<=n;i++) d[i]=INF;
d[s]=; for(int k=;k<=n;k++){
int p,m=INF;
for(int i=;i<=n;i++) if(!used[i]&&d[i]<m) m=d[p=i];
used[p]=;
for(int i=firstt[p];i!=-;i=nextt[i]){
int v=e[i].v;
if(d[v]>d[p]+e[i].cost)
d[v]=d[p]+e[i].cost;
}
}
} void addedges(int u,int v,int w){
nextt[++ecnt]=firstt[u];
e[ecnt].v=v;
e[ecnt].cost=w;
firstt[u]=ecnt;
} int main(){
int a,b,c;
while(scanf("%d %d",&n,&m)!=EOF&&n&&m){
ecnt=;
memset(firstt,-,sizeof(firstt)); for(int i=;i<=m;i++){
scanf("%d %d %d",&a,&b,&c);
addedges(a,b,c);
addedges(b,a,c);
}
dijkstra();
printf("%d\n",d[n]);
}
return ;
}

(3)堆(优先队列)优化
参看紫书上的解释,STL中的pair是专门将两个类型捆绑起来的,

而且pair定义了它自己的排序规则,先比较第一维,相等时才比较第二维,所以需要按照(d[i],i)的顺序组合。

 #include<iostream>
#include<cstdio>
#include<cstring>
#include <cmath>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
#define MP(a,b) make_pair(a,b)
using namespace std; typedef long long LL;
typedef pair<int,int> pii;
const int INF = (<<)-;
const int mod=;
const int maxn=;
int d[maxn],firstt[maxn],nextt[maxn];
int n,m,ecnt; struct edge{
int v,cost;
friend bool operator < (edge a,edge b){
return a.cost>b.cost;
}
}e[maxn]; void addedges(int u,int v,int c){
nextt[++ecnt]=firstt[u];
e[ecnt].v=v;
e[ecnt].cost=c;
firstt[u]=ecnt;
} void dijkstra(int s){
priority_queue<pii> pq;
for(int i=;i<=n;i++) d[i]=INF;
d[s]=;
pq.push(MP(d[s],));
while(!pq.empty()){
pii x=pq.top();pq.pop();
if(d[x.second]<x.first) continue;//当前状态没有现在dis[]数组里面的优,所以不用再继续判断下去
for(int i=firstt[x.second];i!=-;i=nextt[i]){
int v=e[i].v;
if(d[v]>d[x.second]+e[i].cost){
d[v]=d[x.second]+e[i].cost;
pq.push(MP(d[v],v));
}
}
}
} int main(){
int a,b,c;
while(scanf("%d %d",&n,&m)!=EOF&&n&&m){
memset(firstt,-,sizeof(firstt));
ecnt=;
for(int i=;i<=m;i++){
scanf("%d %d %d",&a,&b,&c);
addedges(a,b,c);
addedges(b,a,c);
}
dijkstra();
printf("%d\n",d[n]);
}
return ;
}

(4)用vector存图实现的

 #include<iostream>
#include<cstdio>
#include<cstring>
#include <cmath>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
using namespace std; typedef long long LL;
const int INF = (<<)-;
const int mod=;
const int maxn=;
int d[maxn]; typedef struct edge{
int to,distance;
edge(){}
edge(int to,int distance) :to(to),distance(distance){}
};
typedef pair<int,int> P;
vector<edge> G[maxn];
int n,m,k; void dijkstra(int s){ priority_queue<P,vector<P> ,greater<P> > q;
for(int i=;i < n;i++) d[i]=INF;
d[s]=;
q.push(P(,s)); while(!q.empty()){
P p=q.top();q.pop();
int v=p.second;
if(d[v]<p.first) continue;
for(int i=;i<G[v].size();i++){
edge e=G[v][i]; if(d[e.to] > d[v]+e.distance){ d[e.to] = d[v]+e.distance;
q.push(P(d[e.to],e.to));
}
}
}
} int main(){
while(scanf("%d %d",&n,&m)!=EOF){
if(n==&&m==) break;
for(int i=;i<n;i++) G[i].clear();
while(m--){
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
u--;v--;
G[u].push_back(edge(v,w));
G[v].push_back(edge(u,w));
}
dijkstra();
printf("%d\n",d[n-]);
} return ;
}

2.Bellman_Ford算法

原理:对于图G(V,E),Bellman_Ford是对整个图进行V-1次松弛,每次松弛检查每条边,如果d[v]>d[u]+cost,那么则更新d[v]

应用:可以用来判断负环, 如果没有负权回路的话,那么任意两点间的路径最多经过n-2个点,

即最多松弛n-1次,如果有负权回路,那么第n次松弛操作仍然会成功。

复杂度:O(VE)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include <cmath>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
using namespace std; typedef long long LL;
const int INF = (<<)-;
const int mod=;
const int maxn=;
int d[maxn];
int n,m,ecnt; struct edge{
int u,v,cost;
} e[maxn]; void addedges(int u,int v,int c){
e[++ecnt].u=u;
e[ecnt].v=v;
e[ecnt].cost=c;
} void Bellman_Ford(int s){
for(int i=;i<=n;i++) d[i]=INF;
d[s]=; for(int i=;i<n;i++){
for(int j=;j<=ecnt;j++){
if(d[e[j].v]>d[e[j].u]+e[j].cost)
d[e[j].v]=d[e[j].u]+e[j].cost;
}
}
} int main(){
int a,b,c;
while(scanf("%d %d",&n,&m)!=EOF&&n&&m){
ecnt=;
for(int i=;i<=m;i++){
scanf("%d %d %d",&a,&b,&c);
addedges(a,b,c);
addedges(b,a,c);
}
Bellman_Ford();
printf("%d\n",d[n]);
}
return ;
}

Book 最短路算法的更多相关文章

  1. Dijkstra 最短路算法(只能计算出一条最短路径,所有路径用dfs)

    上周我们介绍了神奇的只有五行的 Floyd 最短路算法,它可以方便的求得任意两点的最短路径,这称为"多源最短路".本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做&q ...

  2. Dijkstra最短路算法

    Dijkstra最短路算法 --转自啊哈磊[坐在马桶上看算法]算法7:Dijkstra最短路算法 上节我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最 ...

  3. Floyd最短路算法

    Floyd最短路算法 ----转自啊哈磊[坐在马桶上看算法]算法6:只有五行的Floyd最短路算法 暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计 ...

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

    前言:针对单源最短路算法,目前最经典的思路即标号算法,以Dijkstra算法和Bellman-Ford算法为根本演进了各种优化技术和算法.针对复杂网络,传统的优化思路是在数据结构和双向搜索上做文章,或 ...

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

    上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”.例如求下图 ...

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

            暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程.         上图中有 ...

  7. Comet OJ 热身赛(E题)(处理+最短路算法)

    dijkstra 已经提交 已经通过 42.86% Total Submission:189 Total Accepted:81 题目描述 Eagle Jump公司正在开发一款新的游戏.泷本一二三作为 ...

  8. 【最短路算法】Dijkstra+heap和SPFA的区别

    单源最短路问题(SSSP)常用的算法有Dijkstra,Bellman-Ford,这两个算法进行优化,就有了Dijkstra+heap.SPFA(Shortest Path Faster Algori ...

  9. 浅谈k短路算法

    An Old but Classic Problem 给定一个$n$个点,$m$条边的带正权有向图.给定$s$和$t$,询问$s$到$t$的所有权和为正路径中,第$k$短的长度. Notice 定义两 ...

随机推荐

  1. DOS系统功能调用表(INT 21H)

    AH 功能 调用参数 返回参数 00 程序终止(同INT 20H) CS=程序段前缀 01 键盘输入并回显 AL=输入字符 02 显示输出 DL=输出字符 03 异步通迅输入 AL=输入数据 04 异 ...

  2. 微信公众号token的asp.net脚本

    老板让我搞一个微信公众号.好吧.前面都很EZ,直到要使用一个token验证服务器的有效性. 看了下文档,大概意思就是微信的服务器用GET请求访问你的服务器. 其中包含了signature,nonce, ...

  3. windbg内核诊断方式--转载

    一.WinDbg是什么?它能做什么? WinDbg是在windows平台下,强大的用户态和内核态调试工具.它能够通过dmp文件轻松的定位到问题根源,可用于分析蓝屏.程序崩溃(IE崩溃)原因,是我们日常 ...

  4. ZOJ2923 Calculate Roads(SPFA上的dp)

    算是学了图dp后的第一次应用吧.题目其实真的是非常不严谨,什么都没说,基本靠猜,而且严格来说数据应该会有爆int的,不过不管那么多啦,思路对了就好- -0 #include<iostream&g ...

  5. iOS第三方地图-百度地图定位的封装

    // // BaiduMapTools.h // baidumapTest // // Created by apple on 15/8/26. // Copyright (c) 2015年 tqh. ...

  6. 高质量图形库:pixellib

    点这里 pixellib 是高质量 2D 图形库: 高质量抗锯齿,矢量图形绘制 多种图像格式: RGB, BGR, ARGB, ABGR, RGBA, BGRA 8 / 15 / 16 / 24 / ...

  7. QT visual stuido 集成插件不能打开ui文件的解决方法(去掉xml的UTF8标记)

    QT visual stuido 集成插件不能打开ui文件的解决方法 visual studio里不能打开这个ui文件,出现warning等解决方法是:于是将<?xml version=&quo ...

  8. QTableWidget使用简单,因为不再存在父节点的关系

    虽然使用比较简单,但亲自过一遍还是有必要的,权当一个学习笔记吧,记录在此. #include "tablewidgetxxx.h" #include <QtGui/QAppl ...

  9. jQuery:balloon气泡提示插件

    插件下载地址:http://file.urin.take-uma.net/jquery.balloon.js-Demo.html <!DOCTYPE html PUBLIC "-//W ...

  10. [iOS]iPhone推送原理

    推送原理,先上图 说一下原理吧, 由App向iOS设备发送一个注册通知 iOS向APNs远程推送服务器发送App的Bundle Id和设备的UDID APNs根据设备的UDID和App的Bundle ...