优化的迪杰斯特拉

迪杰斯特拉大家肯定不陌生,求单源最短路的基础算法。但这算法时间复杂度不尽人意,O(N^2)。所以大佬们就将它给优化了一下,可以达到O(Nlog(N))。那么怎么优化呢?首先我们来看看迪杰斯特拉是怎么求最短路的。这个算法是通过维护一个点集然后再贪心进行求解的。简单来说,就是我已知了n个点,这n个点在目前为止是我知道的可以从源点到达的点,当然它们的路径在目前来说是最优的,那我就通过遍历这些点,来扩展这个点集。朴素的迪杰斯特拉是用一个队列来维护这个点集。这里我们采用最小堆(优先队列)来维护这个点集,以此达到优化的目的。为什么可以这样优化?前面我们说过,迪杰斯特拉是对目前已知的源点可以到达的点进行扩展。假设点i被点now扩展了,那么dist[i]=dist[now]+map[now][i],那么我们何不从最小的dist[now]开始遍历,扩展呢?
我感觉我没讲清楚,但找不出其他描述了。也怪自己也没理解透就写博客了,不过真怕忘了又得在网上胡乱搜博客,还不如记录着,以后理解更深了再改或者自己变菜忘了再返回来翻开都方便。

下面上一个例题代码(洛谷3371 )

#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m,s;
#define inf 2147483647
struct ha
{
    int num;
    long long val;
    bool operator <(const ha &a) const
    {
        return val>a.val;
    }
}node;
struct data
{
    int to,next;
    long long val;
}edge[500005];
int head[10005];
int cnt;
void addEdge(int s,int t,int v)
{
    edge[cnt].to=t;
    edge[cnt].val=v;
    edge[cnt].next=head[s];
    head[s]=cnt++;
}
void solve()
{
    int vis[10005]={0};
    long long dist[10005];
    for(int i=1;i<=n;i++) dist[i]=inf;
    dist[s]=0; vis[s]=0;
    node.num=s; node.val=0;
    priority_queue<ha> qu; qu.push(node);
    while(!qu.empty())
    {
        ha no=qu.top();
        int now = no.num;
        qu.pop();
        if(vis[now]) continue;
        vis[now]=1;
        for(int i=head[now];i!=-1;i=edge[i].next)
        {
            int tto=edge[i].to;
            if(!vis[tto]&&(dist[now]+edge[i].val<dist[tto]))
            {
                dist[tto]=edge[i].val+dist[now];
                node.num=tto; node.val=dist[tto];
                qu.push(node);
            }
        }
    }
    for(int i=1;i<n;i++)
    printf("%lld ",dist[i]);
    printf("%lld\n",dist[n]);
   // return dist[n];
}
int main()
{
   // while(scanf("%d%d",&n,&m) &&n&&m)
    //{
    memset(head,-1,sizeof(head));
    scanf("%d%d%d",&n,&m,&s);
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        addEdge(a,b,c);
    }
    solve();
   // }
    return 0;
}

阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页