(1)Dijkstra算法
1.算法时间复杂度:O(N2)
2.算法特点:
该算法是用来计算从一个点到其他所有点的最短路径算法,也是一种单源最短路径算法。该算法不能处理存在负边权的情况。
3.算法描述
起点:s dis[v]:s到v的最短路径 pre[v]:v的前驱节点
初始化:dis[v]=∞(v≠s) dis[s]=0 pre[s]=0
for(int i=1; i<=n; i++){
//在没有被访问过的点中找一个顶点u使得dis[u]最小。
//u标记为已确定的最短路径。
//找与u相连的每一个未确定的最短路径的顶点v。
if(dis[u]+w[u][v]<dis[v]) { dis[v]=dis[u]+w[u][v]; pre[v]=u; }
}
(2)SPFA算法
1.算法时间复杂度:O(kE)。E=边数,K=常数,平均值=2。
2.something
SPFA是Bellman-Ford算法的一种队列实现,减少了不必要的一些计算。可以说是Bellman-Ford+队列优化。形式上与BFS极其相似的一种单元最短路径算法。
但是在BFS中,只要有个点出队列,就不可能再一次进队列了。但是SPFA不同。在SPFA中,一个点在出队列之后有可能又被放入了队列。
3.算法实现
dis[i]:从起点s到i的最短路径 w[i][j]:链接i和j的边长度 pre[v]:前趋
team[n]:队列 and head=头指针,tail=尾指针
初始化:dis[s]=0,dis[v]=∞(v≠s),将exist数组用memset函数全部赋为false。
//起点入队 do{ //头指针下移1位,取出指向的点u exist[u]=false //for与u相连的所有点v (不要枚举所有点,如果那样好像就成了BMF了(好像不是这样啊。。最起码要慢不少)) if(dis[v]>dis[u]+w[u][v]){ dis[v]=dis[u]+w[u][v]; pre[v]=u; if(!exist[v]){ //尾指针下移1位,v入队列 exist[v]=true; } } }while(head<tail);
下面是杂谈:
这几天在信竞老师那里学最短路径算法。老师说最后学弗洛伊德。。BMF算法由于有SPFA的存在,就不再说了。
这几天在学校的OJand洛谷上写最短路径和一些图论题和一些水题。
等过一段时间我上了弗洛伊德算法后在继续完成剩余的部分吧。
3月25号就市赛了,争取进市队。自己预计了一下,大概有35%的可能性吧。
在这里,还祝要省选的大佬们加油(怎么扯到这上面来了。。)!