Bellman-Ford,感觉不是很好用,边的数目已多就容易超时,但因其可以处理负权图,所以也要会。
循环n-1次,因为图中有N个点,说以最短路最多有n-1条边。而每次循环至少松弛一条边。
1.初始化dis数组,d[s]=0;s为起点;
2.对每一条边e(u,v,w)进行d[e.v]=min(d[e.v],d[e.u]+e.w) -> 松弛操作;
3.重复进行(最多n-1次)2步骤,直到d[i]的值没有更新为止;
4.判断负环。结束3步骤后,在执行一遍2步骤,判断d[e.v]>d[e.u]+e.w,但不进行更新,如果有一条边为真,则说明存在负环,即无法求最短路。
struct Edge {
inr u,v;
int w;
}ed[MAX]; //记录边
int dis[MAX];
bool Bellman_Ford (){
for (int i=0;i<n;i++){ //初始化
dis[i]=INF;
}
bool flag;
for (int i=0;i<n-1;i++){//n-1次循环
flag=false;
for (int j=0;j<2*m+w;j++){
if (dis[ed[j].v]>dis[ed[j].u]+ed[j].w){ //松弛操作
dis[ed[j].v]=dis[ed[j].u]+ed[j].w;
flag=true;
}
}
if (flag==false)
break;
}
flag=0;
for (int j=0;j<2*m+w;j++){ //判断负环
if (dis[ed[j].v]>dis[ed[j].u]+ed[j].w){
flag=1;
}
}
return flag;
}
Bellman-Ford有个优化叫SPFA还没学。下次再补