博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【模板】最短路
阅读量:5113 次
发布时间:2019-06-13

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

①多源最短路

弗洛伊德算法(Floyd)

弗洛伊德算法基本思想就是:

(1) 最开始只允许经过1号顶点进行中转;

(2) 接下来只允许经过1和2号顶点进行中转,以此类推;

(3) 直到最后允许经过1~n号所有顶点进行中转,求任意两点之间的最短路程。

算法基本思路:在只经过前k号点的前提下,更新从i号顶点到j号顶点的最短路程

#include
using namespace std;const int INF=0x3f3f3f3f;const int M=1e3+5;int n,m,e[M][M];void init(){ for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i==j) e[i][j]=0; else e[i][j]=INF; int u,v,w; for(int i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); e[u][v]=w; }}void floyd(){ init(); for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(e[i][j]>e[i][k]+e[k][j]) e[i][j]=e[i][k]+e[k][j];}int main(){ cin>>n>>m; floyd(); return 0; }
floyd算法模板

 


②单源最短路

迪杰斯特拉算法(Dijkstra)

(1) 最基础的版本,时间复杂度O(2n2)

dist数组:初始点到其余各个顶点的最短路径;

vis数组:下标和dist数组对应;

<1>若值为false,则该点为未确定点,dist数组里的对应值是未确定的;

<2>若值为true,则该点为已确定点,dis数组里的对应值是确定的;

算法基本思路:每次找到离源点(我们目前指定的初始点就是1号顶点)最近的一个顶点,然后以该顶点为中心进行扩展,

不断更新源点到其余所有点的最短路径。

#include
using namespace std;const int INF=0x3f3f3f3f;const int maxSize=1e3+5;int n,m,e[maxSize][maxSize],dist[maxSize];void dijkstra(int x){ int vis[maxSize],i,j,u,minn; for(i=1;i<=n;i++) { dist[i]=e[x][i]; vis[i]=0; } vis[x]=1; for(i=1;i
dist[u]+e[u][j]) dist[j]=dist[u]+e[u][j]; }}int main(){ int i,j,u,v,w,x; while(cin>>n>>m) { for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(i==j)e[i][j]=0; else e[i][j]=INF; for(i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&w); e[u][v]=w; } cin>>x; dijkstra(x); for(i=1;i<=n;i++) cout<
<<" "; } return 0;}
dijkstra基础算法

(2) 链式前向星版本,时间复杂度O(n2

dis数组:初始点s到其余各个顶点的最短路径;

算法基本思路:从初始点开始作为中介点u,不断加入以中介点u为起点的已存在边的终点v,如果dis[u]+这条边的权值w<dis[v],则更新dis[v]。

#include
using namespace std;#define MAX 105 #define INF 0x3f3f3f3fint head[MAX],dis[MAX],cn;struct edge{ int w,to,next;}e[MAX*MAX];void add(int u,int v,int w){ e[++cn].w=w; e[cn].next=head[u]; e[cn].to=v; head[u]=cn; } void dij(int s){ int he=0,ta=0,qu[MAX*MAX],i; qu[ta++]=s; dis[s]=0; while(he
dis[u]+x.w) { dis[x.to]=dis[u]+x.w; qu[ta++]=x.to; } } }} int main(){ int n,m,i; while(scanf("%d%d",&n,&m)!=EOF) { memset(dis,INF,sizeof(dis)); memset(head,-1,sizeof(head)); for(i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); } int s; cin>>s; dij(s); for(i=1;i<=n;i++) cout<
<<" "; }}
dijkstra链式前向星版本

(3) vector邻接表版本,时间复杂度O(n2)

算法基本思路:与链式前向星版本同理。

#include
using namespace std;#define MAX 10005#define INF 0x3f3f3f3ftypedef pair
pii;vector
vec[MAX];int dis[MAX];void dij(int s){ memset(dis,INF,sizeof(dis)); dis[s]=0; int qu[MAX],he=0,ta=0,i; qu[ta++]=s; while(he
dis[u]+w) { dis[v]=dis[u]+w; qu[ta++]=v; } } }}int main(){ int n,m,i; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1;i<=m;i++) { int u,v,w; scanf("%d%d%d",&u,&v,&w); vec[u].push_back(pii(v,w)); } int s; cin>>s; dij(s); for(i=1;i<=n;i++) cout<
<<" "; } return 0;}
dijkstra邻接表版本

转载于:https://www.cnblogs.com/kannyi/p/8675687.html

你可能感兴趣的文章
遍历Map对象
查看>>
MySQL索引背后的数据结构及算法原理
查看>>
#Leetcode# 209. Minimum Size Subarray Sum
查看>>
SDN第四次作业
查看>>
DM8168 DVRRDK软件框架研究
查看>>
django迁移数据库错误
查看>>
yii 跳转页面
查看>>
洛谷 1449——后缀表达式(线性数据结构)
查看>>
Data truncation: Out of range value for column 'Quality' at row 1
查看>>
Dirichlet分布深入理解
查看>>
(转)Android之发送短信的两种方式
查看>>
字符串处理
查看>>
HtmlUnitDriver 网页内容动态抓取
查看>>
ad logon hour
查看>>
获得进程可执行文件的路径: GetModuleFileNameEx, GetProcessImageFileName, QueryFullProcessImageName...
查看>>
证件照(1寸2寸)拍摄处理知识汇总
查看>>
罗马数字与阿拉伯数字转换
查看>>
Eclipse 反编译之 JadClipse
查看>>
Python入门-函数
查看>>
[HDU5727]Necklace(二分图最大匹配,枚举)
查看>>