高效求最短路SPFA算法(C语言)

来源:互联网 发布:iphone5越狱软件 编辑:程序博客网 时间:2024/05/22 15:05

看这个之前建议理解了Bellman-Ford算法,因为本算法可以看做是对其的优化。

优化一、改用邻接表存图。邻接表的使用,即一个点配一个链表。

优化二、用列表来存储松弛边缘(Bellman-Ford算法过程可以看作一个图,从其中的一个起点开始松弛,一层一层松弛下去,直到遍布全图),不再需要每次遍历全图。


其它好像没变,还是用d[i]来表示i点距源点最短距离。

多了一个标志数组(防止重复入队),记录每点入队次数的数组(若某点入队次数大于n,则有负环)


http://www.cnblogs.com/scau20110726/archive/2012/11/18/2776124.html里面步骤写得很好

另附手写C语言模板:

#include<stdio.h>
#define MAXN 100
#define inf 1<<30




typedef struct list{
int v;
int cost;
struct list *next;

}list;
list a_list[MAXN];
int n,que[MAXN],used[MAXN],d[MAXN],c[MAXN];
int main()
{



return 0;
}


void init_alist(int n)
{ int i;
for(i=0;i<n;i++)
a_list[i].next=NULL;

}


void add_ege(int u,int v,int cost)   //注意v是从0开始,记得对数据-1
{ list *p,*q;
p=&a_list[u];
while(p->next!=NULL)
p=p->next;
p->v=v;
p->cost=cost;
q=(list *)malloc(sizeof(list));
q->next=NULL; 
p->next=q; 
}


int spfa(int s)
{ int i,u,v,l,r,L,R;
list *p;
l=0,r=-1,L=0,R=-1;
memset(used,0,sizeof(used));
memset(c,0,sizeof(c));
for(i=0;i<n;i++)
d[i]=inf;
d[s]=0;
que[++r]=s;++R;
used[s]=1;
c[s]++;
while(R>=L)
{ u=que[l++];L++;
if(l>MAXN-1) l=0; 
used[u]=0;
for(p=&a_list[u];p->next!=NULL;p=p->next)
{ v=p->v;
if(d[v]>d[u]+p->cost)
d[v]=d[u]+p->cost;
if(!used[v])
{ que[++r]=v;++R;
if(r>=MAXN-1) r=-1; 
used[v]=1;
c[v]++;

}
if(c[v]>n)
return 0;
}


}


return 1;


}


原创粉丝点击