Dijkstra算法的两种实现方法

第一种

复杂度( O(V^2) )
每次从尚未使用过的点中找出一个距离最小的点,然后更新相关的边

int cost[MAX_V][MAX_V];
int d[MAX_V];
bool used[MAX_V];
int V;
void dijkstra_1(int s)
{
    fill(d,d + V,INF);
    fill(used,used + V,false);
    d[s] = 0;
    while(true)
    {
        int v = -1;
        for(int u = 0; u < V; u++)
            // 从尚未使用过的顶点中选择一个距离最小的顶点
            if(!used[u] && (v == -1 || d[u] < d[v]))
                v = u;
        if(v == -1)
            break;
        used[v] = true;
        for(int u = 0; u < V; u++)
            d[u] = min(d[u], d[v] + cost[v][u]);
    }
}

第二种

在第一种的基础上优化,复杂度( O(E * log V) )
第一种在边较少的情况下,查找距离最小的点浪费了太多时间
这里采用优先队列便是为了减少在查找上浪费的时间

struct edge
{
    int to,cost;
};
typedef pair<int,int> P;
int V;
vector<edge> G[MAX_V];
int d[MAX_V];
void dijkstra_2(int s)
{
    priority_queue<P, vector<P>, greater<P> > que;
    fill(d,d + V,INF);
    d[s] = 0;
    que.push(P(0,s));
    while( !que.empty() )
    {
        P p = que.top();
        que.pop();
        int v  = p.second;
        if (d[v] < p.first) continue;
        for(int i = 0; i < G[v].size(); i++)
        {
            edge e = G[v][i];
            if(d[e.to] > d[v] + e.cost)
            {
                d[e.to] = d[v] + e.cost;
                que.push(P(d[e.to],e.to));
            }
        }
    }
}
点赞