Book 最短路算法
用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 最短路算法的更多相关文章
- Dijkstra 最短路算法(只能计算出一条最短路径,所有路径用dfs)
上周我们介绍了神奇的只有五行的 Floyd 最短路算法,它可以方便的求得任意两点的最短路径,这称为"多源最短路".本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做&q ...
- Dijkstra最短路算法
Dijkstra最短路算法 --转自啊哈磊[坐在马桶上看算法]算法7:Dijkstra最短路算法 上节我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最 ...
- Floyd最短路算法
Floyd最短路算法 ----转自啊哈磊[坐在马桶上看算法]算法6:只有五行的Floyd最短路算法 暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计 ...
- 近十年one-to-one最短路算法研究整理【转】
前言:针对单源最短路算法,目前最经典的思路即标号算法,以Dijkstra算法和Bellman-Ford算法为根本演进了各种优化技术和算法.针对复杂网络,传统的优化思路是在数据结构和双向搜索上做文章,或 ...
- 【啊哈!算法】算法7:Dijkstra最短路算法
上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”.例如求下图 ...
- 【啊哈!算法】算法6:只有五行的Floyd最短路算法
暑假,小哼准备去一些城市旅游.有些城市之间有公路,有些城市之间则没有,如下图.为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程. 上图中有 ...
- Comet OJ 热身赛(E题)(处理+最短路算法)
dijkstra 已经提交 已经通过 42.86% Total Submission:189 Total Accepted:81 题目描述 Eagle Jump公司正在开发一款新的游戏.泷本一二三作为 ...
- 【最短路算法】Dijkstra+heap和SPFA的区别
单源最短路问题(SSSP)常用的算法有Dijkstra,Bellman-Ford,这两个算法进行优化,就有了Dijkstra+heap.SPFA(Shortest Path Faster Algori ...
- 浅谈k短路算法
An Old but Classic Problem 给定一个$n$个点,$m$条边的带正权有向图.给定$s$和$t$,询问$s$到$t$的所有权和为正路径中,第$k$短的长度. Notice 定义两 ...
随机推荐
- Sqli-labs less 48
Less-48 本关与less-46的区别在于报错注入不能使用,不进行错误回显,因此其他的方法我们依旧是可以使用的. 可以利用sort=rand(true/false)进行判断. http://127 ...
- (转)Learning to Rank for IR的评价指标—MAP,NDCG,MRR
转自:http://www.cnblogs.com/eyeszjwang/articles/2368087.html MAP(Mean Average Precision):单个主题的平均准确率是每篇 ...
- POJ 3662
Telephone Lines Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4591 Accepted: 1693 D ...
- H5+ and mui学习记录
基础 1.H5+ 定义实现了一些调用原生方法的对象 2.其他的原生方法可以通过Native.js调用 webview 3.webview是调用原生界面的H5+对象 4.单个webview只承载单个页面 ...
- poj 1062(有限制的最短路)
题目链接:http://poj.org/problem?id=1062 思路:要求对于最短路上的点,不能出现等级之差大于m,于是我们可以枚举,假设酋长的等级为level,于是这个区间范围[level- ...
- android sdk启动报错error: could not install *smartsocket* listener: cannot bind to 127.0.0.1:5037:
android sdk启动报错error: could not install *smartsocket* listener: cannot bind to 127.0.0.1:5037: 问题原因: ...
- eq相等 ,ne、neq不相等 EL表达式
eq相等,ne.neq不相等, gt大于, lt小于 gte.ge大于等于 lte.le 小于等于 not非 mod求模 is [not] div by是否能被某数整除 is [n ...
- 客户端用httpurlconnection来进行http连接的
客户端用httpurlconnection来进行http连接的,并设置restful风格 请求响应流程 设置连接参数的方法 setAllowUserInteraction setDoInput set ...
- iOS开发-UISlider改变图片透明度
拖动条是通过滑块的位置来标识数值,而且拖动条允许用户拖动滑块来改变值.因此,拖动条通常用于对系统的某种数值进行调节,如调节亮度,透明度,音量等. 一.属性介绍 @property(nonatomic) ...
- JavaWeb笔记——三大组件之监听器
1 JavaWeb监听器概述 在JavaWeb被监听的事件源为:ServletContext.HttpSession.ServletRequest,即三大域对象. l 监听域对象“创建”与“销毁”的 ...