首页 > 代码库 > 图论——Dijkstra算法

图论——Dijkstra算法

图论其实是比较难的一种题型,但是一些模板题,是没有什么太大难度的!

这里给大家带来的是迪杰斯特拉(Dijkstra)算法。

迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。

是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。

迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

#include<cstdio>
#include<cstring>
#include<queue>
#define reg register
using namespace std;
const int N=100001;
const int M=100001;
int n,m,s,t,d[N];
int edge,e[M],b[M],w[M],fir[N];
void add(reg int x,reg int y,reg int z)
{
    e[++edge]=y;
    w[edge]=z;
    b[edge]=fir[x];
    fir[x]=edge;
}
struct node
{
    int i,di;
};
bool operator<(node a,node b)
{
    return a.di>b.di;
}
priority_queue<node>que;
void input()
{
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(reg int i=1;i<=m;i++)
    {
        reg int x,y,z;
        scanf("%d%d%d",&x,&y,&z);
        add(x,y,z);
        add(y,x,z);
    }
    memset(d,0x7f,sizeof(d));
    que.push((node){s,0});
    d[s]=0;
}
void work()
{
    for(;!que.empty();)
    {
        node t=que.top();
        que.pop();
        if(d[t.i]!=t.di)
            continue;
        for(reg int k=fir[t.i];k;k=b[k])
            if(t.di+w[k]<d[e[k]])
            {
                d[e[k]]=t.di+w[k];
                que.push((node){e[k],d[e[k]]});
            }
    }
}
void output()
{
    printf("%d\n",d[t]);
}
int main()
{
    input();
    work();
    output();
    return 0;
}

我们看到,一般的Dijkstra算法好像不需要STL,可是这个优先队列呢?它是进行堆优化的。

理论上,堆优化可以是Dijkstra算法时间复杂度降到O(n log n),这样不是很好吗?多写几行,时间快不少,何乐而不为?

需要注意的大概就这些,希望大家继续努力,天天AC!

备注:

标准模板题是 [USACO09OCT] Heat Wave 热浪。

链接参考(来自“洛谷”):http://www.luogu.org/problem/show?pid=1339

图论——Dijkstra算法