Dijkstra+优先队列 堆优化

代码

#include <cstdio>
#include <queue>
#include <vector>
#define MAXN 200010
#define INF 0x3fffffff
using namespace std;
struct edge{
    int v,w;
    edge(int v, int w):v(v),w(w){}
};
vector <edge> mp[MAXN];
int dis[MAXN];
bool vis[MAXN];
int n,m,s;
struct node{
    int v,dis;
    node(int v, int dis):v(v),dis(dis){}
    const bool operator < (const node &a) const{
        return a.dis < dis;
    }
};
priority_queue <node> q;

int read(){
    char ch;int s=0;
    ch = getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
    return s;
}

void dj(){
    for(register int i=1;i<=n;i++)
        dis[i]=INF;
    dis[s]=0;
    q.push(node(s, 0));
    while(!q.empty()){
        node cur = q.top();
        q.pop();
        if(vis[cur.v])  continue;
        vis[cur.v] = 1;
        for(register int i=0;i<mp[cur.v].size();i++){
            edge to = mp[cur.v][i];
            if(vis[to.v]) continue;
            if(dis[to.v]>to.w+dis[cur.v]){
                dis[to.v]=to.w+dis[cur.v], q.push(node(to.v, dis[to.v]));
            }
        }
    }
    for(register int i=1;i<=n;i++)
        printf("%d ", dis[i]);
}

int main()
{
    n=read(),m=read(),s=read();
    for(register int i=1;i<=m;i++){
        int u,v,w;
        u=read(),v=read(),w=read();
        mp[u].push_back(edge(v, w));
    }
    dj();
    return 0;
}

关于堆优化

传统\(Dijkstra\),在选取中转站时,是遍历取当前最小距离节点,但是我们其实可以利用小根堆(STL的priority_queue)优化这个过程,从而大大降低复杂(\(O(V2+E) -> O((V+E)lgV)\))

另外,需要注意,因为\(Dijkstra\)本质是贪心,每一次选择中转站必须保证最优,而负边权会使当前中转站不为最优,所以不能处理含有负边权的图

原文地址:https://www.cnblogs.com/santiego/p/10458039.html

时间: 2024-10-03 23:01:02

Dijkstra+优先队列 堆优化的相关文章

POJ 1511 Invitation Cards 【最短路,spfa算法,Dijkstra算法堆优化】

Invitation Cards Time Limit: 8000MS   Memory Limit: 262144K Total Submissions: 25219   Accepted: 8346 Description In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They wan

Dijkstra算法堆优化(vector建图)

#include<iostream> #include<algorithm> #include<string.h> #include<stdio.h> #include<queue> #include <vector> #include <map> int s,t; int n,m; using namespace std; const int INF=99999999; struct Node{ int to; int

POJ 3013 Big Christmas Tree【最短路变形,DIjkstra堆优化+spfa算法】

Big Christmas Tree Time Limit: 3000MS   Memory Limit: 131072K Total Submissions: 23064   Accepted: 4987 Description Christmas is coming to KCM city. Suby the loyal civilian in KCM city is preparing a big neat Christmas tree. The simple structure of t

Heap+Dijkstra堆优化的Dijkstra

前面说到"原生的Dijkstra",由于Dijkstra采用的是贪心策略,在贪心寻找当前距离源结点最短的结点时需要遍历所有的结点,这必然会导致效率的下降,时间复杂度为n^n.因此当数据量较大时会消耗较长时间.为了提高Dijkstra的效率,只有对Dijkstra的贪心策略进行改进. 由于Dijkstra采用的贪心策略是每次寻找最短距离的结点并将其放入存放所有已知最短距离结点的S集合中,可以联想到堆以及优先级队列这些数据结构,这些结构都能非常高效地提供当前状态距离最短的结点.实践也可以证

迪杰斯特拉算法(Dijkstra) (基础dij+堆优化) BY:优少

首先来一段百度百科压压惊... 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法.是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题.迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止. 让我来翻译一下:Dijkstra可以求出一个点到一个图中其他所有节点的最短路径,故也称对于单源最短路径的一种解法 算法实现步骤: a.初始时,只包括源点,即S = {v},v的距离为0.U包含除v以外的其他顶点,即

dijkstra算法及其优化

dijkstra算法是经典的贪心算法.基本的想法是,有两个集合S和E,开始S集合中只有一个起点,E集合中有剩下的其他点.遍历E集合中的所有点,找出与起点距离最近的一个点,将其加入集合S,并用该点去更新起点到其他点的最短路径. 由动图结合上面的思路,我们可以看出,算法的基本框架是: 1 1.初始化 2 for i(0 -> n - 1) 3 { 4 2.找出距离起点最近的点 5 3.标记该点加入集合S 6 4.用新加入集合S的点去更新起点到其他点的最短距离 7 } 1.其中初始化包括了距离数组di

【最短路】Dijkstra+ 链式前向星+ 堆优化(优先队列)

Dijkstra+ 链式前向星+ 优先队列   Dijkstra算法 Dijkstra最短路算法,个人理解其本质就是一种广度优先搜索.先将所有点的最短距离Dis[ ]都刷新成∞(涂成黑色),然后从起点x (Dis[x]= 0, Dis[]值最小 )开始查询:先将x 加入(涂成灰色),对x 的所有边进行遍历,对所有搜索到的点x+ 1 进行松弛(刷新),若经过x 点的松弛,得到的距离小于原来的值:Dis[x]+ dis(x, x+ 1) < Dis[x+ 1], 则用新值刷新,把x+ 1加入(涂成灰

eoj1817 dijkstra单元最短路径 普通方法+二叉堆优化

求出有n(1 < n < 600)个结点有向图中,结点1到结点n的最短路径. Input 第一行有2个整数n和m(0 < m <= n*(n-1)/2),接下来m行每行有三个整数u,v,w结点u到v之间有一条权为w的边(w<1000000). Output 输出结点1到结点n之间的最短路径,如果1到n之间不存在路径,输出 -1. Sample Input 3 3 1 2 10 2 3 15 1 3 30 题目分析:dijkstra单元最短路径. 一.最短路径的最优子结构性质

【日常学习】【Dijkstra堆优化】codevs2038 香甜的黄油题解

转载请注明出处 [ametake版权所有]http://blog.csdn.net/ametake 先放上题目,出自USACO 题目描述 Description 农夫John发现做出全威斯康辛州最甜的黄油的方法:糖.把糖放在一片牧场上,他知道N(1<=N<=500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油.当然,他将付出额外的费用在奶牛上. 农夫John很狡猾.他知道他可以训练这些奶牛,让它们在听到铃声时去一个特定的牧场.他打算将糖放在那里然后下午发出铃声,以至他可以在晚上挤奶. 农