bellman-ford
求单源最短路,可以判断有无负权回路(若有,则不存在最短路),时效性较好,时间复杂度O(VE)。
bool bellman(){
int i, j;
for(i=1; i<n; i++){
for(j=0; j<num; j++){
if(d[edge[j].s]+edge[j].v<d[edge[j].e])
d[edge[j].e]=d[edge[j].s]+edge[j].v;
}
}
for(j=0; j<num; j++){
if(d[edge[j].s]+edge[j].v<d[edge[j].e])
return false;
}
return true;
}
spfa
是Bellman-Ford的队列优化,时效性相对好,时间复杂度O(kE)。(k<<V)。
与Bellman-ford算法类似,SPFA算法采用一系列的松弛操作以得到从某一个节点出发到达图中其它所有节点的最短路径。所不同的是,SPFA算法通过维护一个队列,使得一个节点的当前最短路径被更新之后没有必要立刻去更新其他的节点,从而大大减少了重复的操作次数。
bool spfa(int g, int st){
int i, head, s;
for(i=1; i<=n; i++){
inqueue[i]=0;
d[i]=INF;
}
queue<int > q;
d[st]=0;
inqueue[st]=1;
q.push(st);
while(!q.empty()){
head=q.front();
q.pop();
inqueue[head]=0;
s=pre[g][head];
while(s!=-1){
if(d[edge[g][s].v]>d[head]+edge[g][s].w){
d[edge[g][s].v]=d[head]+edge[g][s].w;
if(!inqueue[edge[g][s].v]){
inqueue[edge[g][s].v]=1;
q.push(edge[g][s].v);
}
}
s=edge[g][s].next;
}
}
return true;
}
FLOYD
求多源、无负权边的最短路。用矩阵记录图。时效性较差,时间复杂度O(V^3)。
void floyd(){
int i, j, k;
for( k=0; i<n; k++)
for( i=0; i<n; i++)
for( j=0; j<n; j++){
if( i==k || i==j || j==k ) continue;
if( len[i][k]+ len[k][j]< len[i][j]){
len[i][j]= len[i][k]+ len[k][j];
next[i][j]= next[k][j];
}
}
}
void road(){//floyd 路径记录
next[i][j]=j; //init();
next[i][j]=k; //save
int i=s, j=e;
printf("%d ", i);
while( next[i][j]!=j){
printf("%d ",next[i][j]);
i= next[i][j];
}
printf("%d\n", j);
}
dijkstra
求单源、无负权的最短路。时效性较好,时间复杂度为O(V*V+E)。
void dijkstra(int graph[][101], int n)
{
int cov[101];
memset(cov,0,sizeof(cov));
memset(k,0,sizeof(k));
int flag, i, j,min,max=0;
for(i=1;i<=n;i++)
k[i] = graph[1][i];
for(i=2;i<=n;i++)
{
min=MAX;
flag = 0;
for(j=2;j<=n;j++)
{
if(k[j]<min && cov[j]== 0)
{
min = k[j];
flag = j;
}
}
cov[flag] = 1;
for(j = 2; j <= n; j++)
{
if(cov[j]==0&&graph[flag][j]>=0&&min+graph[flag][j]<k[j])
{
k[j] = graph[flag][j]+min;
}
}
}
}