最短路

  最短路是图论的基础部分。其中学过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),优先推荐使用。

你可能感兴趣的:(最短路)