图论算法-Dijkstra

原理

Dijkstra是一个神奇的最短路径算法,它的优点在于它可以稳定的时间内求出一张图从某点到另一点的距离。它的工作原理非常简单,思路类似于广搜。在搜索前,将每个点的颜色设为白色,第一次将源点Insert进入集合,将源点的最短路(用Dis数组表示)设为0,然后在它的所有白色孩子边上进行一遍搜索,并将经过的点的颜色设为黑色。在搜到更优的距离后对Dis进行适当的更新,让Disi每次都表示到点i的最短距离。搜到汇点时停止。此时,DisT表示的就是到达T的最短路径。

代码

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <utility>

#define debug(x) std::cout << #x << " = " << x << std::endl

struct
{
    int to, nex, v;
} e[100001];
int head[100001] = { 0 }, dis[100001] = { 0 };
bool b[100001] = { false };

void Insert(const int x, const int y, const int w)
{
    static int tot = 0;
    tot++;
    e[tot].nex = head[x];
    e[tot].to = y;
    e[tot].v = w;
    head[x] = tot;
}

int n, m, S, T;

void Dijkstra()
{
    typedef std::pair<int, int> pii;
    std::priority_queue<pii, std::vector<pii>, std::greater<pii> > q;
    int now, j;
    std::memset(dis, 0x7f, sizeof dis);
    q.push(std::make_pair(0, S));
    while (!q.empty())
    {
        now = q.top().first;
        j = q.top().second;
        q.pop();
        if (b[j])
            continue;
        b[j] = true;
        dis[j] = now;
        for (int t = head[j]; t; t = e[t].nex)
            if (dis[e[t].to] > now + e[t].v)
                q.push(std::make_pair(now + e[t].v, e[t].to));
    }
}

int main(int argc, char ** argv)
{
    while (~std::scanf("%d%d", &n, &m))
    {
        std::memset(dis, 0, sizeof dis);
        for (size_t i = 0; i < m; i++)
        {
            int x, y, w;
            std::cin >> x >> y >> w;
            Insert(x, y, w);
        }
        S = 1, T = n;
        Dijkstra();
        std::cout << dis[T] << std::endl;
    }
    return 0;
}
posted @ 2017-04-27 19:23  Edward_Tsui  阅读(148)  评论(0编辑  收藏  举报