




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
最短路径2019/3/29最短路径2019/3/29单源最短路径 Dijkstra算法及堆优化 Bellman-Ford算法 SPFA算法任意两点间的最短路 Folyd算法
应用:传递闭包最短路问题的扩展与应用
差分约束系统
CONTENTS单源最短路径CONTENTS单源最短路径SSSP,SingleSourceShortestPathProblem/01单源最短路径SSSP,/01单源最短路径问题4给定一张带权图以及一个起点S,终点T,求S到T的最短路径。单源最短路径问题4给定一张带权图以及一个起点S,终点T,求SDijkstra算法5适用于正权图的单源最短路径问题。算法流程:定义源点为S,数组dis[x]为源点S到x的最短路径初始化dis数组为INF,并令dis[S]=0遍历数组,找到未访问点中dis[x]最小值的下标x,将x点标记为已访问松弛原理,遍历与x直接相邻的点y,更新dis[y]的最小值重复第2,3步,直到所有点都已被访问Dijkstra算法5适用于正权图的单源最短路径问题。松弛原理、三角不等式6if(dis[u]+w[u][v]<dis[v])
dis[v]=dis[u]+w[u][v];Dis[A]Dis[B]Dis[C]step10INFINFstep20206step30min(dis[b],dis[c]+w[b][c])=min(20,13)=136松弛原理、三角不等式6if(dis[u]+w[u][v]朴素Dijkstra算法7intdijkstra(ints,intt){ memset(vis,0,sizeofvis); for(inti=0;i<n;i++)dis[i]=(i==s?0:INF); //初始化dis for(inti=0;i<n;i++) { intx,m=INF; for(inty=0;y<n;y++)if(!vis[y]&&dis[y]<=m)m=dis[x=y]; //未访问点中dis最小值 vis[x]=1; for(inty=0;y<n;y++)dis[y]=min(dis[y],dis[x]+w[x][y]); //松弛操作 } returndis[t];}复杂度为O(n^2).朴素Dijkstra算法7intdijkstra(intDijkstra算法的优化8朴素Dijkstra算法通过O(n)遍历dis数组实现每次找到未访问的最小值结点x,重复n次操作,复杂度为O(n^2)考虑优化过程中每次寻找dis值最小值的过程以dis值为key维护小顶堆,每次取堆顶结点x,对其相邻节点进行松弛操作总复杂度为O((n+m)logn),在稀疏图中作用比较明显structnode{intu,dis;booloperator<(constnode&no)const{returndis>no.dis;}};Dijkstra算法的优化8朴素Dijkstra算法通过O(堆优化Dijkstra9voiddijkstra(ints){for(inti=1;i<=n;i++)dis[i]=inf;dis[s]=0;priority_queue<node>que;que.push({0,s});while(!que.empty()){nodef=que.top();que.pop();intu=f.u,d=f.dis;if(d!=dis[u])continue;for(inti=head[u];~i;i=edge[i].nex){intv=edge[i].to,w=edge[i].w;if(dis[u]+w<dis[v]){dis[v]=dis[u]+w;que.push({v,dis[v]});}}}}堆优化Dijkstra9voiddijkstra(int带负权边的最短路径问题10基于贪心性质,Dijkstra算法不能处理带负权边的最短路问题。对于可能负权边的图上的最短路径,我们引入Bellman-Ford算法求解。带负权边的最短路径问题10基于贪心性质,Dijkstra算法Bellman-Ford算法11Bellman-Ford算法基于动态规划,反复使用已有的边来更新最短距离,算法的核心思想是松弛。即if(dis[v]<dis[u]+map[u][v])dis[v]=dis[u]+map[u][v],与dijkstra算法相同如果没有负权回路,Bellman-Ford算法应该会在n-1次松弛后结束如果有负权回路,第n次操作仍然会成功,Bellman-Ford算法就是利用这个性质判定负环。算法流程:定义源点为S,数组dis[x]为源点S到x的最短路径初始化dis数组为INF,并令dis[S]=0对于每条边(u,v),如果dis[u]!=INF且dis[v]>dis[u]+map[u][v],更新dis[v]重复步骤2n-1次或直到某次中不再更新,进入步骤4对于每条边(u,v),如果dis[u]!=INF且dis[v]>dis[u]+map[u][v],则存在负权回路复杂度为O(n*m)Bellman-Ford算法11Bellman-Ford算法Bellman-Ford算法12boolbellmanFord(ints){ for(inti=0;i<n;i++)dis[i]=i==s?0:INF; for(inti=0;i<n-1;i++) //n-1次松弛操作 { for(intu=0;u<n;u++) //取以u为起点的所有边进行更新 { if(dis[u]==INF)continue; for(intk=head[u];~k;k=edge[k].nex) dis[edge[i].to]=min(dis[edge[i].to],dis[u]+edge[i].w); } } for(intu=0;u<n;u++) //判断负环 { if(dis[u]==INF)continue; for(intk=head[u];~k;k=edge[i].nex) if(dis[edge[k].to]>dis[u]+edge[k].w)returnfalse; } returntrue;}Bellman-Ford算法12boolbellmanFoSPFA算法130.关于SPFA它死了 ——NOI2018在非负权边的单源最短路径问题中,不要使用SPFA
请使用稳定O(nlogn)的堆优化Dijkstra
在含负权边的最短路径问题中,SPFA的复杂度最坏情况下复杂度等同于Bellman-Ford为什么
如何看待SPFA算法已死这种说法?
如何卡SPFA?
SPFA算法130.关于SPFASPFA算法14SPFA算法是在Bellman-Ford算法基础上进行改进的一种算法,使其能够在计算带负边权图的单源最短路径的情况下,时间复杂度大幅度降低。算法流程:初始化dis数组为INF,并令dis[S]=0,新建队列,讲源点S入队,标记S已在队列中;取出队首结点u,标记出队,对u出队的次数进行检查,如果大于n,说明出现负环,算法结束否则,遍历x所连接的边,如果边k的另一端的节点v可以更新(松弛原理),则更新dis[v]并检查v是否在队列中,如果不在,加入队列重复执行步骤2,直到队列为空SPFA算法14SPFA算法是在Bellman-Ford算法SPFA算法15boolspfa(ints){for(inti=0;i<n;i++)dis[i]=INF;queue<int>que;que.push(s);dis[s]=0,vis[s]=true;while(!que.empty()){intu=que.front();que.pop();vis[u]=false,cnt[u]++;if(cnt[u]>n)returnfalse; //存在负环for(inti=head[u];~i;i=edge[i].nex){ //更新相邻结点disif(dis[edge[i].to]>dis[u]+edge[i].w){if(!vis[edge[i].to])que.push(edge[i].to),vis[edge[i].to];dis[edge[i].to]=dis[u]+edge[i].w;}}}returntrue;}SPFA算法15boolspfa(ints){任意两点间的最短路Supportingtexthere.Whenyoucopy&paste,choose"keeptextonly"option./02任意两点间的最短路Supportingtexthere.Floyd算法17F[i][j]=min(F[i][j],F[i][k]+F[k][j]);这个算法是RobertW.Floyd和StephanWarshall在1962年各自独立发表的Floyd算法17Floyd算法18for(inti=1;i<=n;i++)for(intj=1;j<=n;j++)for(intk=1;k<=n;k++)F[i][j]=min(F[i][j],F[i][k]+F[k][j]);在设定边权之前,需要初始化F[i][j]=i==j?0:
INF;Floyd算法基于动态规划的思想,用于求解任意两点间的最短路问题,复杂度为O(n^3)Floyd算法18for(inti=1;i<=n传递闭包19传递闭包,即在离散数学中,在集合X上的二元关系R的传递闭包是包含R的X上的最小的传递关系。如,集合X为一系列人的集合,二元关系R为“为父子”,则R的传递闭包即为关系:x是y的祖先;再如,集合X为空港的集合,而关系xRy为“从空港x到空港y有直航”,则R的传递闭包是:可能经一次或多次航行从x飞到y以一个表示两点间直接关系的矩阵R,通过Floyd算法,求出其传递闭包(即每两点存在的直接或间接关系)传递闭包19传递闭包,即在离散数学中,在集合X上的二元关POJ-366020有n头牛比赛,m种比赛结果,求一共有多少头牛的排名被确定了。其中如果a战胜b,b战胜c,则也可以说a战胜c,即可以传递胜负。求能确定排名的牛的数目。POJ-366020有n头牛比赛,m种比赛结果,求一共有多少POJ-366021如果一头牛被x头牛打败,打败了y头牛,且x+y=n-1,则这头牛的排名被确定了。则我们只要确定任意两头牛的胜负关系,再遍历所有牛的状态,判断x+y是否等于n-1,将满足这个条件的牛数目加起来即为所求解。将其确定胜负过程抽象为传递闭包,对原矩阵跑Floyd。传递闭包中矩阵上点的入度和出度即为胜负次数。POJ-366021如果一头牛被x头牛打败,打败了y头牛,且最短路问题的扩展与应用Supportingtexthere.Whenyoucopy&paste,choose"
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 生物样本液氮罐租赁与生物样本安全存储及运输服务合同
- 纺织品质量检验补充合同
- 《晶体管开关特性》课件
- XXX学校校园体育一小时活动安全应急预案范文
- 《神经系统结构概要》课件
- 商品管理与营销策略
- 会展策划师职业培训体系
- 《临床护理操作》课件
- 动土作业安全培训
- 食品安全案例警示与维权指南
- 辽宁点石联考2025届高三5月份联合考试-政治试卷+答案
- 2025-2030年中国铜冶炼行业前景预测与投资价值研究报告
- 2025年官方兽医答题题库附答案详解(达标题)
- 校长在全体教师大会上讲话:五把钥匙解锁教师从容人生
- 国企物业考试试题及答案
- 2024年湖南省城步苗族自治县事业单位公开招聘医疗卫生岗笔试题带答案
- 以患者为中心的医疗数据管理系统-基于区块链技术
- 2025至2030中国寺庙经济市场深度调研与未来前景发展研究报告
- 2025-2030全球及中国工程机械租赁行业市场现状供需分析及投资评估规划分析研究报告
- 食用菌品牌形象塑造策略-全面剖析
- 电厂脱硫维护合同协议
评论
0/150
提交评论