bellman-ford可以有负权,但不能有负权回路,
spfa是bellman-ford的队列优化,时间发咋度o(ke),其中k为所有顶点进队的平均次数,可以证明k一般小于等于2。
dijkstra不可以有负权,但效率比bellman-ford快,o(2n次方),用二叉堆优化o((m+n)log n),斐波纳契堆能稍微提高一些性能,让算法运行时间达到o(m + n log n)。
floyed算每对顶点之间的最短路,前几个是单源的
noip提高组多练搜索,学会动态规划差不多了,其他的模拟提都简单,主要是多练题
纯手打
嘤了,这必然是最短路径问题,那么对应的自然就是最短路径算法。虽然我才做过这个问题,但是为了锻炼题主自主思考和搜集资料的能力,只能提示几种算法:
1、Dijkstra算法
2、Bellman算法
3、A算法
4、SPFA算法
其实下面这些都算是Dijkstra的升级版本(应对负权之类的问题)
网上现成的代码很多,可以直接找了debug,我必然被采纳
意思是对于每个顶点v∈V,都设置一个属性d[v],用来描述从源点s到v的最短路径上权值的上界,称为最短路径估计(shortest-pathestimate)。
π[v]代表S到v的当前最短路径中v点之前的一个点的编号,我们用下面的Θ(V)时间的过程来对最短路径估计和前趋进行初始化。
INITIALIZE-SINGLE-SOURCE(G,s)。
1、for each vertex v∈V[G]。
2、do d[v]←∞。
3、π[v]←NIL。
4、d[s]←0。
扩展资料:
经过初始化以后,对所有v∈V,π[v]=NIL,对v∈V-{s},有d[s]=0以及d[v]=∞。
在松弛一条边(u,v)的过程中,要测试是否可以通过u,对迄今找到的v的最短路径进行改进;如果可以改进的话,则更新d[v]和π[v]。一次松弛 *** 作可以减小最短路径估计的值d[v],并更新v的前趋域π[v](S到v的当前最短路径中v点之前的一个点的编号)。下面的伪代码对边(u,v)进行了一步松弛 *** 作。
参考资料来源:百度百科-松弛
这是我写的程序和运行的结果,如果有不会的地方依然可以问我。
/
首先我想说明几点问题。
1我不知道你的题意中的路径是单向的还是双向的,不过我把路径设置成双向的了
2说一下我程序的输入,首先输入一个n,表示该图中有n条路;然后有n行,每行
两个数x, y(1<=x, y<=99),表示这两个地点有一条路径。最后输入两个数,
表示计算这两点之间所有的路径
3我的思路用的是深搜,不过广搜也是可以的
/
#include <stdioh>
#include <mathh>
int path[100][100];///path[i][j]为0表示i, j两点之间不通,为1表示有一条路
int stack[120], m=1, n, x, y;///存储路径
void dfs(int p)
{
int i, j;
for(i=1; i<=100; i++)
{
if(path[p][i]==1)
{
if(i == y)///如果深搜到了终点,就输出刚才经过的路径
{
for(j=0; j<m; j++)
{
printf("%-5d", stack[j]);
}
printf("%-5d\n", y);
}
else///如果该点不是终点
{
stack[m] = i;///将该点存起来
m++;
dfs(i);///接着深搜
m--;
}
}
}
}
int main()
{
int i, j;
memset(path, 0, sizeof(path));
scanf("%d", &n);
for(i=0; i<n; i++)
{
scanf("%d %d", &x, &y);
path[x][y] = path[x][y] = 1;///这两点之间有路径
}
scanf("%d %d", &x, &y);
stack[0] = x;
dfs(x);
}
MBT Can Help Reduce Fatigue
MBT shoes reduce fatigue MBT shoesArch support,jordan shoes 为时下最流行的mini-cinch设计, foot by a full three feet by the force into a force to relieve foot fatigue;Vibram Five Fingers Shoes foot while promoting blood circulation and relieve foot fatigue In order to use shoe polish to achieve best results, use with cool shoes, spray,jordan shoes, this product can be very easy to maintain long-lasting fresh shoes mbt sandalsOf course,jordan shoes Air Jordans Fusion Shoes,jordan shoes, this product can also be other types of use of MBT shoes, the effect is also very good Meanwhile, the heel height of 5 cm which can achieve the effect of increased hiddencheap mbt shoes Health shoes can become a trend Many people think that older and need to correct the gait of healthy people would be wearing shoesmbtThe fatigue can also become the most popular! MBT can lead body movement and encourage the use of neglected muscleNew mbt shoesIt can improve posture and gait adjustment and shape physiqueAt the same time,jordan shoes,it help improve the back,jordan shoes cheap jordan shoes, buttocks, legs and feet
tag:
MBT shoes
Vibram Five Fingers Shoes
mbt sandals
cheap mbt shoes
mbt
New mbt shoes
差分约束系统。。dijkstra往往不能用
SPFA一般来说比不优化的dijkstra(O(n2))好
SPFA也有自己的优化SLF LLL和前向星 比加堆的dijkstra好写
。。还有就是可以判负环吧
看待SPFA算法已死这种说法:
对SPFA的一个很直观的理解就是由无权图的BFS转化而来。在无权图中,BFS首先到达的顶点所经历的路径一定是最短路(也就是经过的最少顶点数),所以此时利用数组记录节点访问可以使每个顶点只进队一次,但在带权图中,最先到达的顶点所计算出来的路径不一定是最短路。
一个解决方法是放弃数组,此时所需时间自然就是指数级的,所以我们不能放弃数组,而是在处理一个已经在队列中且当前所得的路径比原来更好的顶点时,直接更新最优解。
定理:
只要最短路径存在,上述SPFA算法必定能求出最小值。证明:每次将点放入队尾,都是经过松弛 *** 作达到的。换言之,每次的优化将会有某个点v的最短路径估计值d[v]变小。
所以算法的执行会使d越来越小。由于我们假定图中不存在负权回路,所以每个结点都有最短路径值。因此,算法不会无限执行下去,随着d值的逐渐变小,直到到达最短路径值时,算法结束,这时的最短路径估计值就是对应结点的最短路径值。
用于解决最短路径问题的算法被称做“最短路径算法”,有时被简称作“路径算法”。最常用的路径算法有:
Dijkstra算法、A算法、SPFA算法、Bellman-Ford算法和Floyd-Warshall算法,本文主要介绍其中的三种。
最短路径问题是图论研究中的一个经典算法问题,旨在寻找图(由结点和路径组成的)中两结点之间的最短路径。
算法具体的形式包括:
确定起点的最短路径问题:即已知起始结点,求最短路径的问题。
确定终点的最短路径问题:与确定起点的问题相反,该问题是已知终结结点,求最短路径的问题。在无向图中该问题与确定起点的问题完全等同,在有向图中该问题等同于把所有路径方向反转的确定起点的问题。
确定起点终点的最短路径问题:即已知起点和终点,求两结点之间的最短路径。
全局最短路径问题:求图中所有的最短路径。
Floyd
求多源、无负权边的最短路。用矩阵记录图。时效性较差,时间复杂度O(V^3)。
Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题。
Floyd-Warshall算法的时间复杂度为O(N^3),空间复杂度为O(N^2)。
Floyd-Warshall的原理是动态规划:
设Di,j,k为从i到j的只以(1k)集合中的节点为中间节点的最短路径的长度。
若最短路径经过点k,则Di,j,k = Di,k,k-1 + Dk,j,k-1;
若最短路径不经过点k,则Di,j,k = Di,j,k-1。
因此,Di,j,k = min(Di,k,k-1 + Dk,j,k-1 , Di,j,k-1)。
在实际算法中,为了节约空间,可以直接在原来空间上进行迭代,这样空间可降至二维。
Floyd-Warshall算法的描述如下:
for k ← 1 to n do
for i ← 1 to n do
for j ← 1 to n do
if (Di,k + Dk,j < Di,j) then
Di,j ← Di,k + Dk,j;
其中Di,j表示由点i到点j的代价,当Di,j为 ∞ 表示两点之间没有任何连接。
Dijkstra
求单源、无负权的最短路。时效性较好,时间复杂度为O(VV+E),可以用优先队列进行优化,优化后时间复杂度变为0(vlgn)。
源点可达的话,O(VlgV+ElgV)=>O(ElgV)。
当是稀疏图的情况时,此时E=VV/lgV,所以算法的时间复杂度可为O(V^2) 。可以用优先队列进行优化,优化后时间复杂度变为0(vlgn)。
Bellman-Ford
求单源最短路,可以判断有无负权回路(若有,则不存在最短路),时效性较好,时间复杂度O(VE)。
Bellman-Ford算法是求解单源最短路径问题的一种算法。
单源点的最短路径问题是指:给定一个加权有向图G和源点s,对于图G中的任意一点v,求从s到v的最短路径。
与Dijkstra算法不同的是,在Bellman-Ford算法中,边的权值可以为负数。设想从我们可以从图中找到一个环
路(即从v出发,经过若干个点之后又回到v)且这个环路中所有边的权值之和为负。那么通过这个环路,环路中任意两点的最短路径就可以无穷小下去。如果不处理这个负环路,程序就会永远运行下去。 而Bellman-Ford算法具有分辨这种负环路的能力。
SPFA
是Bellman-Ford的队列优化,时效性相对好,时间复杂度O(kE)。(k< 与Bellman-ford算法类似,SPFA算法采用一系列的松弛 *** 作以得到从某一个节点出发到达图中其它所有节点的最短路径。所不同的是,SPFA算法通过维护一个队列,使得一个节点的当前最短路径被更新之后没有必要立刻去更新其他的节点,从而大大减少了重复的 *** 作次数。
SPFA算法可以用于存在负数边权的图,这与dijkstra算法是不同的。
与Dijkstra算法与Bellman-ford算法都不同,SPFA的算法时间效率是不稳定的,即它对于不同的图所需要的时间有很大的差别。
在最好情形下,每一个节点都只入队一次,则算法实际上变为广度优先遍历,其时间复杂度仅为O(E)。另一方面,存在这样的例子,使得每一个节点都被入队(V-1)次,此时算法退化为Bellman-ford算法,其时间复杂度为O(VE)。
SPFA算法在负边权图上可以完全取代Bellman-ford算法,另外在稀疏图中也表现良好。但是在非负边权图中,为了避免最坏情况的出现,通常使用效率更加稳定的Dijkstra算法,以及它的使用堆优化的版本。通常的SPFA。
以上就是关于关于Dijkstra、SPFA、Bellman-Ford、Floyed算法的问题全部的内容,包括:关于Dijkstra、SPFA、Bellman-Ford、Floyed算法的问题、求这道题用C语言怎么写、编程里的“松弛”是什么意思等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)