最短路径之 Dijkstra模板

一:时间复杂度为O(V*V)的Dijkstra

const int Max_v = 100 + 10;
const int INF = 1<<30;
int cost[Max_v][Max_v];//权值
int d[Max_v];//顶点s出发最短距离
bool used[Max_v];//以使用过的图
int V;//顶点数
int Edge;//边数

void dijkstra(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]);
        }
    }
  printf("%d\n",d[V-1]);
}

二:时间复杂度为O(E*logV)的Dijkstra(优先级队列优化后的)

const int maxn = 1000 + 10;
const int INF = 1<<30;
typedef pair<int, int> P;
int N, R;
struct edge
{
    int to, cost;
};
vector<edge> G[maxn];
int d[maxn];  //最短路径

void solve()
{
    priority_queue<P, vector<P>, greater<P> > que;
    fill(d, d+N, INF);  //最短距离

    d[0] = 0;
    que.push(P(0,0));
    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));
            }

        }
    }
    printf("%d\n",d[N-1]);
}

三:模板题目HDU2544

Description

在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt。但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗?

Input

输入包括多组数据。每组数据第一行是两个整数N、M(N<=100,M<=10000),N表示成都的大街上有几个路口,标号为1的路口是商店所在地,标号为N的路口是赛场所在地,M则表示在成都有几条路。N=M=0表示输入结束。接下来M行,每行包括3个整数A,B,C(1<=A,B<=N,1<=C<=1000),表示在路口A与路口B之间有一条路,我们的工作人员需要C分钟的时间走过这条路。

输入保证至少存在1条商店到赛场的路线。

Output

对于每组输入,输出一行,表示工作人员从商店走到赛场的最短时间

Sample Input

 2 1
1 2 3
3 3
1 2 5
2 3 5
3 1 2
0 0 

Sample Output

 3
2 

第一种AC代码

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

const int Max_v = 100 + 10;
const int INF = 1<<30;
int cost[Max_v][Max_v];//权值
int d[Max_v];//顶点s出发最短距离
bool used[Max_v];//以使用过的图
int V;//顶点数
int Edge;//边数

void dijkstra(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]);
        }
    }
  printf("%d\n",d[V-1]);
}
int main()
{
#ifdef xxz
    freopen("in.txt","r",stdin);
#endif // xxz
    int Case;
    while(scanf("%d%d",&V,&Edge) != EOF)
    {
        if(V == 0 && Edge == 0) break;
        for(int i = 0; i < Max_v; i++) fill(cost[i],cost[i]+Max_v,INF);//注意每次都要初始化权值,否则WA
        for(int i = 0 ; i < Edge; i++)
        {
            int u,v,value;
            scanf("%d%d%d",&u,&v,&value);
            u--,v--;
            cost[u][v] = cost[v][u] = value;
        }
       dijkstra(0);
    }
    return 0;
}

第二种AC代码(堆优化)

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

const int maxn = 1000 + 10;
const int INF = 1<<30;
typedef pair<int, int> P;
int N, R;
struct edge
{
    int to, cost;
};
vector<edge> G[maxn];
int d[maxn];  //最短路径

void solve()
{
    priority_queue<P, vector<P>, greater<P> > que;
    fill(d, d+N, INF);  //最短距离

    d[0] = 0;
    que.push(P(0,0));
    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));
            }

        }
    }
    printf("%d\n",d[N-1]);
}

int main()
{
    int i, a, b, c;
    edge e;
    while(~scanf("%d%d",&N,&R))
    {
        if(N == 0 && R == 0) break;
        for(i = 0; i < maxn; i++) G[i].clear();

        for(i=0; i<R; ++i)
        {
            scanf("%d%d%d", &a, &b, &c);
            a--,b--;
            e.to = b, e.cost = c;
            G[a].push_back(e);
            e.to = a;
            G[b].push_back(e);
        }
        solve();
    }
    return 0;
}
时间: 2024-10-22 02:17:23

最短路径之 Dijkstra模板的相关文章

最短路径 一 Dijkstra 模板(O(n^2))

题目传送:http://hihocoder.com/problemset/problem/1081 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define INF 0x03F3F3F3F 5 #define N 1024 6 int path[N], vis[N]; 7 int cost[N][N],lowcost[N]; 8 void Dijkstra(int n, int beg){

HDU 2544:最短路( 最短路径入门 &amp;&amp;Dijkstra &amp;&amp; floyd )

最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 30972    Accepted Submission(s): 13345 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找

最短路径算法-Dijkstra算法的应用之单词转换(词梯问题)

一,问题描述 在英文单词表中,有一些单词非常相似,它们可以通过只变换一个字符而得到另一个单词.比如:hive-->five:wine-->line:line-->nine:nine-->mine..... 那么,就存在这样一个问题:给定一个单词作为起始单词(相当于图的源点),给定另一个单词作为终点,求从起点单词经过的最少变换(每次变换只会变换一个字符),变成终点单词. 这个问题,其实就是最短路径问题. 由于最短路径问题中,求解源点到终点的最短路径与求解源点到图中所有顶点的最短路径复

最短路径之Dijkstra算法

Dijkstra算法: 首先,引进一个辅助向量D,它的每个分量D[i]表示当前所找到的从始点v到每个终点vi的的长度:如D[3]=2表示从始点v到终点3的路径相对最小长度为2.这里强调相对就是说在算法过程中D的值是在不断逼近最终结果但在过程中不一定就等于长度.它的初始状态为:若从v到vi有弧,则D为弧上的权值:否则置D为∞.显然,长度为 D[j]=Min{D | vi∈V} 的路径就是从v出发的长度最短的一条.此路径为(v,vj). 那么,下一条长度次短的是哪一条呢?假设该次短路径的终点是vk,

最短路径问题-Dijkstra

概述 与前面说的Floyd算法相比,Dijkstra算法只能求得图中特定顶点到其余所有顶点的最短路径长度,即单源最短路径问题. 算法思路 1.初始化,集合K中加入顶点v,顶点v到其自身的最短距离为0,到其它所有顶点为无穷. 2.遍历与集合K中结点直接相邻的边(U,V,C),其中U属于集合K,V不属于集合K,计算由结点v出发,按照已经得到的最短路径到达U,再由U经过该边达到V时的路径长度.比较所有与集合K中结点直接相邻的非集合K结点该路径长度,其中路径长度最小的顶点被确定为下一个最短路径确定的结点

单源最短路径算法---Dijkstra

Dijkstra算法树解决有向图G=(V,E)上带权的单源最短路径问题,但是要求所有边的权值非负. 解题思路: V表示有向图的所有顶点集合,S表示那么一些顶点结合,从源点s到该集合中的顶点的最终最短路径的权值(程序中用dist[i]表示)已经确定.算法反复选择具有最短路径估计的顶点u 属于 V-S(即未确定最短路径的点,程序中finish[i]=false的点),并将u加入到S中(用finish[i]=true表示),最后对u的所有输出边进行松弛. 程序实现:      输入数据: 5 7 0

有向有权图的最短路径算法--Dijkstra算法

Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的最短路径算法, 在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等.注意该算法要求图中不存在负权边. 问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径.(单源最短路径) 2.算

图的单源最短路径:Dijkstra算法实现

本文介绍的是图的非负权值的单源最短路径问题.问题的提出是,对于有权图D,t提供源点v,要找到从v到其他所有点的最短路径,即单源最短路径问题,在本文中,解决这一问题,是普遍比较熟悉的Dijkstra算法. 算法核心思想参见维基.简而言之,设集合S存放已经求出了最短路径的点.初始状态S中只有一个点v0,之后每求得v0到vn的最短路径,就会更新v0到所有vn邻接的点的一致的最短路径(不一定是最终的最短路径),如此重复,每次会确定v0到一个点的最短路径,确定好的点加入S中,直至所有点进入S结束.在本文中

单源最短路径(dijkstra算法)php实现

做一个医学项目,其中在病例评分时会用到单源最短路径的算法.单源最短路径的dijkstra算法的思路如下: 如果存在一条从i到j的最短路径(Vi.....Vk,Vj),Vk是Vj前面的一顶点.那么(Vi...Vk)也必定是从i到k的最短路径.Dijkstra是以最短路径长度递增,逐次生成最短路径的算法.例如:对于源顶点V0,首先选择其直接相邻的顶点中长度最短的顶点Vi,那么当前已知可得从V0到达Vj顶点的最短距离dist[j]=min{dist[j],dist[i]+cost[i][j]}.假设G