Dijkstra算法

题目:luogu P4779

分析:实现Dijkstra算法,基于binary heap可以得到$O((m+n)\log{n})$的复杂度,基于Fibonacci heap可以得到$O(m+n\log{n})$的复杂度。这里我们采用优先队列priority_queue. 注意:Dijkstra算法只能求解边权为非负的图。

代码:

#include<iostream>
#include<queue>
#include<vector>
#include<functional>
#include<cstdio>
#include<string.h>
using namespace std;
struct
{
    int weight;//边权
    int toVer;//边(u,v)对应的v
    int nex;//边(u,v1)上一条共起点的边(u,v2)的编号
} edge[200005];
int utoe[100005];
int dis[100005];
int vis[100005];
struct node
{
    int distance;
    int vertex;
    node(){}
    node(int x, int y)
    {
        distance = x;
        vertex = y;
    }
};
bool operator>(node a, node b)
{
    return a.distance > b.distance;
}
int INF = 1e9 + 1;
priority_queue< node, vector<node>, greater<node> >q;
void Dijkstra(int s)
{
    dis[s] = 0;
    q.push(node(0, s));
    node top_ele;
    int e_idx;
    int v_temp;
    int dis_temp;
    while (!q.empty())
    {
        top_ele = q.top();
        q.pop();
        if (vis[top_ele.vertex] == 1)
            continue;
        vis[top_ele.vertex] = 1;
        e_idx = utoe[top_ele.vertex];
        while (e_idx>0)
        {
            v_temp = edge[e_idx].toVer;
            if (vis[v_temp] == 0)
            {
                dis_temp = top_ele.distance + edge[e_idx].weight;
                if (dis_temp < dis[v_temp])
                {
                    dis[v_temp] = dis_temp;
                    q.push(node(dis_temp, v_temp));
                }
            }
            e_idx = edge[e_idx].nex;
        }
    }
}
int main()
{
    int n, m, s;
    int u, v, w;
    int i;
    int id_e;
    while (scanf("%d%d%d", &n, &m, &s) == 3)
    {
        id_e = 0;
        memset(utoe, 0, sizeof(utoe));
        for (i = 0; i < m; i++)
        {
            scanf("%d%d%d", &u, &v, &w);
            edge[++id_e].weight = w;
            edge[id_e].toVer = v;
            edge[id_e].nex = utoe[u];
            utoe[u] = id_e;
        }
        for (i = 1; i <= n; i++)
            dis[i] = INF;
        memset(vis, 0, sizeof(vis));
        Dijkstra(s);
        for (i = 1; i <= n; i++)
            printf("%d ", dis[i]);
        printf("\n");
    }
    return 0;
}
View Code

posted on 2020-11-19 14:35  小叶子曰  阅读(104)  评论(0编辑  收藏  举报

导航