最短路的四种算法
来源:互联网 发布:java流程控制 编辑:程序博客网 时间:2024/06/05 11:06
求最短路一般有四种方法:
1.floyd dp思想dis[i][j]=min(dis[i][j]+dis[i][k]+dis[k][j]) 时间复杂度O(N^3)
2.dijkstra 邻接矩阵。 时间复杂度O(N^2)
3.dijkstra 邻接表+优先级队列优化。 时间复杂度O(M*lgN)
4.bellman-Ford 用于解决含有负权值得最小路问题 时间复杂度O(M*N)5.SPFA是bellman-ford的改进算法(队列实现),效率也更高 复杂度为:O(kE)E为边数,k一般为2或3
1.floyd算法:可以求任意两点之间的最短距离。解决传递背包和最小环问题~,不能解决负权回路。
for(int k=0;k<a;k++)//经过k点{ for(int i=0;i<a;i++)//起点 { for(int j=0;j<a;j++)//终点 { If(w[i][j]>w[i][k]+w[k][i]; w[i][j]=w[i][k]+w[k][i]; } }}//如果经过k点距离变短,那么w[i][j]不变,否则更新。可以理解为对于1点而言,经过或者不经过1点求个最短,然后在1点的基础上对于2点,求个最短路...。2.dijkstra 邻接矩阵:没办法解决负边权的最短路径。
采用的是邻接矩阵来存的,第一点浪费的空间比较多,第二点我们知道算法的时间复杂度在O(n*n)
(1)确定数组—邻接矩阵(赋值0或者inf)
(2)输入数组-邻接矩阵
(3)确定距离dis数组//用1号顶点到其余各边的距离初始化;
(4)判断某一点是否当过起始点bool数组
(5)最关键!!循环n-1次,
先找一行中的最小值确保该行没有遍历过。
找到之后通过最小值所在行更新dis数组。
//初始化 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",&t1,&t2,&t3); e[t1][t2]=t3; } //初始化dis数组,这里是1号顶点到其余各个顶点的初始路程 for(i=1;i<=n;i++) dis[i]=e[1][i]; //book数组初始化 for(i=1;i<=n;i++) book[i]=0; book[1]=1; //Dijkstra算法核心语句 for(i=1;i<=n-1;i++)//循环n-1次,每次都找到一行中的最小值,也就是对应的最小的点。 { min=inf; for(j=1;j<=n;j++)//找离某一点最近的点 { if(book[j]==0 && dis[j]<min) { min=dis[j]; u=j; } } book[u]=1; for(v=1;v<=n;v++)//找到最小点的最小距离的点,有的话就更新。 { if(e[u][v]<inf) { if(dis[v]>dis[u]+e[u][v]) dis[v]=dis[u]+e[u][v]; } } }
3.dijkstra 邻接表+优先级队列优化。
重载一个比较函数
struct node{ int x,d; node(){} node(int a,int b){x=a;d=b;} bool operator < (const node & a) const { if(d==a.d) return x<a.x; else return d > a.d; } }; //定义一个结构体,重载比较函数
- vector<node> eg[Ni];
- int dis[Ni],n;
void Dijkstra(int s) { int i; for(i=0;i<=n;i++) dis[i]=INF; dis[s]=0; //用优先队列优化 priority_queue<node> q; q.push(node(s,dis[s])); while(!q.empty()) { node x=q.top();q.pop(); for(i=0;i<eg[x.x].size();i++) { node y=eg[x.x][i]; if(dis[y.x]>x.d+y.d) { dis[y.x]=x.d+y.d; q.push(node(y.x,dis[y.x])); } } } }4.bellman-Ford一:初始化所有点。每一个点保存一个值,表示从原点到达这个点的距离,将原点的值设为0,其它的点的值设为无穷大(表示不可达)。二:进行循环,循环下标为从1到n-1(n等于图中点的个数)。在循环内部,遍历所有的边,进行松弛计算。三:遍历途中所有的边(edge(u,v)),判断是否存在这样情况: d(v) > d (u) + w(u,v) 则返回false,表示途中存在从源点可达的权为负的回路。
struct node{ int from,to,w;};node edge[100];bool Ford(){ for(i = 1; i <= n; i ++) dis[i] = inf; dis[1] = 0; for(i = 1; i <= n; i ++) { flag = false; for(j = 1; j <= m; j ++) { x = edge[i].from ; y = edge[i].to ; z = edge[i].w ; if(dis[y] > dis[x] + z) { dis[y] = dis[x] + z; flag = true; } } if(!flag) break; //如果更新到n遍,还能够继续更新dis数组,说明存在负权环 if(flag&&i == n) return false;//返回false表示这个图存在负权环 } return true;//返回true表示求最短路成功 }
5.SPFA
阅读全文
0 0
- 最短路的四种算法总结
- 最短路的四种算法
- 最短路四种算法
- HDU 2544 最短路重刷,四种算法
- 最短路的几种常用算法
- 主要的4种最短路算法
- 最短路算法的整理
- 图的最短路算法
- 最短路的各种算法
- HDU 2544 最短路(各种最短路算法的实现)
- HDU 2544 最短路(各种最短路算法的实现)
- [ZZ]最短路的算法---Dijkstra算法
- 最短路算法的SPFA算法
- hdu2544 最短路(三种基本最短路算法)
- 最短路的三种算法(Floyd、Dijkstra、SPFA)
- 【1874】畅通工程续 (最短路四种算法)(HDU)
- 最短路-四种算法复杂度分析比较 HDU-1874 畅通工程
- 最短路的Warshall-Floyd算法
- C#禁用USB的两种方法(附代码)
- java基础
- [FAQ12964][OPP]无法通过蓝牙分享及接收apk应用文件
- 金蝶K3客户端:组件<KdSvrMgr>无法正常工作 排查分析步骤
- WebView页面上的图片点击的时候加载到Viewpager显示并且可以放大缩小
- 最短路的四种算法
- 九的余数
- 线段树总结
- 找朋友
- 自动轮播+无限轮播
- 信用卡评分模型(R语言)
- ReactNative-综合案例(02)
- linux系统下硬盘挂载
- 我为什么学python?