最短路是图论的基础部分。其中学过4个主要算法,分别是Floyed,Dijkstra,Ford,SPFA。SPFA作为Ford的队列实现,有一定的优化,因此就不说Ford了。
首先两点间距离读取都是一样的。
memset(f,0x3f,sizeof(f)); for(int i=1;i<=n;++i) f[i][i]=0; for(int i=1;i<=e;++i) { scanf("%d%d%d",&a,&b,&distance); f[a][b]=distance; f[b][a]=distance; }
Floyed。特点是解决了所有点的最短路,且试用于负边权的情况。但时间复杂度是O(n^3),所以一般用处不大。
#define FOR(i,x,y) for(int i=x;i<=y;++i) #define MIN(a,b) a<b?a:b FOR(k,1,n) FOR(i,1,n) FOR(j,1,n) f[i][j]=MIN(f[i][j],f[i][k]+f[k][j]);
Dijkstra。特点是计算了单点间最短路,不能在负边权的时候使用。时间复杂度O(n^2),可以考虑使用。
int Dijkstra(int st,int en) { memset(vis,0,sizeof(vis)); FOR(i,1,n) ans[i]=f[st][i]; FOR(i,1,n) { minn=0x3f3f3f3f; k=-1; FOR(j,1,n) if(!vis[j]&&ans[j]<minn) { minn=ans[j]; k=j; } if(k==-1) break; vis[k]=true; FOR(j,1,n) ans[j]=MIN(ans[j],ans[k]+f[k][j]); } return ans[en]; }
SPFA。特点是计算单点间最短路,可以计算负边权最短路,不能直接算负边权回路。时间复杂度O(E),优先推荐使用。
原文:http://www.cnblogs.com/cons/p/5187282.html