最短路-Bellman-ford
1 对于所以边权都大于等于0的图,任意两个点之间的最短路,显然不会经过重复的顶点或者边,也就是说任意一条最短路经过的顶点不会超过n个,边不会超过n-1条
2 Bellman-Ford的核心思想是松弛操作,对于边(u,v),用dist(u)和l(u,v)的和尝试更新dist(v
------ dist(v)=min(dist(v),dist(u)+l(u,v));
3在最短路存在的情况下,由于一次迭代会使最短路的边数至少加一,而S到每个顶点的最短路经过的边数最多为n-1,因此整个算法最多会经过n-1轮迭代,每一轮迭代的复杂度为O(m)-(每条边枚举到一次),所以总的算法时间复杂度为O(nm);
4-当S点出发能到达一个负环后,就会进行n轮以上的迭代(如果大于等于n轮迭代,就存在负环)
5Code:
struct Edge{
int x,y,v;
}edge[M+5];
int n,m,dist[N+5],pre[N+5];
int shortestpath(int s,int t){
memset(dist,-1,sizeof(dist));//假设-1为无穷大
dist[s]=0;
while(true){
bool ok=false;
for(int i=1;i<=m;i++){
int x=edge[i].x,y=edge[i].y,v=edge[i].v;
if(dist[x]!=-1){
if(dist[y]==-1||(dist[x]+v<dist[y]))
{
dist[y]=dist[x]+v;
pre[y]=x;
ok=true;
}
}
}
if(!ok) break;
}
return dist[t];
}
–一开始将除了s顶点外的距离赋值为无穷大,起点s的距离赋值为0,每次迭代中,遍历所有的边,尝试用松弛操作更新距离数组
6队列优化(SPFA):在每一次迭代时,只有上一次迭代中被更新了距离的点,才有可能去更新其它节点。因此,在每一次迭代时,我们将更新过距离的顶点加入一个队列(如果该顶点不存在队列中),在下一轮迭代时只需要遍历队列中的顶点连出去的边即可