dijkstra

堆优化的dijkstra算法

旧巷老猫 提交于 2019-11-28 10:29:27
#include<bits/stdc++.h> using namespace std; #define ll long long #define P pair<int,int> const ll INF=1e18; const int N=2e5+10; int head[N],ver[N],edge[N],Next[N],n,m,tot,v[N]; ll d[N]; void add(int x,int y,int z) { ver[++tot]=y; edge[tot]=z; Next[tot]=head[x]; head[x]=tot; } void dijkstra(int s) { priority_queue<pair<int,int> >q; for(int i=1;i<=n;i++) { d[i]=INF; v[i]=0; } d[s]=0; q.push(make_pair(0,s)); while(q.size()) { int x=q.top().second; q.pop(); if(v[x]) continue; v[x]=1; for(int i=head[x];i;i=Next[i]) { int y=ver[i],z=edge[i]; if(d[y]>d[x]+z) { d[y]=d[x]+z; q.push(make_pair(-d[y],y))

POJ-1511(Dijkstra+优先队列优化)

好久不见. 提交于 2019-11-28 10:00:21
Invitation Cards POJ-1511 从这道题我还是发现了很多的问题,首先就是快速输入输出,这里的ios::---这一行必须先放在main函数第一行,也就是输入最开始的前面,否则系统疯狂报WA。 其次就是,ios的位置没有错之后又疯狂地报TLE,就是超时了,这个问题要不就是算法的复杂度,还有就是输入输出还是不够快,所以首先排除输入输出的问题,所以我把ios改成了scanf所以这题就过了。 事实证明,ios的方法还是没有scanf快,所以以后还是使用scanf. 其次就是这个算法本身的问题,这个其实已经比n*n的算法快多了,由于本题的数据量太大,这个版本也是很险才过的。 关于本题的思路主要就是正着走一遍,然后倒着走一遍,最后累加起来就可以了。 推荐一个多方法的博客: https://blog.csdn.net/qq_39665840/article/details/81437812 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<queue> #include<algorithm> #include<vector> using namespace std; const int INF=0x3f3f3f3f; int p,q;//p-stops;q-lines

Dijkstra algorithm optimization/caching

假如想象 提交于 2019-11-28 09:54:46
问题 I have the following Dijkstra algorithm with 3 input variables (start, stop and time). It takes about 0.5-1s to complete. My hosting provider says it's using too much resources and I should implement some caching mechanism. My question is, how? Because I have 3 variables, if only one of them changes - the whole result is different (because I have some additional statements with time, nevermind). So how to implement some caching mechanism or do some optimisation? I have 1700 nodes . <?php

Which datatype to use as queue in Dijkstra's algorithm?

早过忘川 提交于 2019-11-28 07:32:25
I'm trying to implement Dijkstra's algorithm in Java (self-study). I use the pseudo-code provided by Wikipedia ( link ). Now near the end of the algorithm, I should decrease-key v in Q; . I guess i should have implemented Q with a BinaryHeap or something like that? What would be the right (built-in) datatype to use here? private void dijkstra(int source) { int[] dist = new int[this.adjacencyMatrix.length]; int[] previous = new int[this.adjacencyMatrix.length]; Queue<Integer> q = new LinkedList<Integer>(); for (int i = 0; i < this.adjacencyMatrix.length; i++) { dist[i] = this.INFINITY; previous

luogu 4366 [Code+#4]最短路 Dijkstra + 位运算 + 思维

浪子不回头ぞ 提交于 2019-11-28 04:05:46
Code: #include <cstdio> #include <algorithm> #include <cstring> #include <queue> #define N 100004 #define M 4000000 #define inf 10000000000000 #define ll long long #define setIO(s) freopen(s".in","r",stdin) using namespace std; struct Node { int u; ll dis; Node(int u=0,ll dis=0):u(u),dis(dis){} bool operator<(Node b)const { return b.dis<dis; } }; priority_queue<Node>q; int n,m,C,edges,s,t; ll d[N]; int hd[N],nex[M],to[M],val[M],done[N]; inline void addedge(int u,int v,int c) { nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c; } inline void Dijkstra() { int i,u,v; for(i=0;i<=n;++i) d[i]

Dijkstra算法堆优化详解

99封情书 提交于 2019-11-28 03:54:39
DIJ算法的堆优化 DIJ算法的时间复杂度是 \(O(n^2)\) 的,在一些题目中,这个复杂度显然不满足要求。所以我们需要继续探讨DIJ算法的优化方式。 堆优化的原理 堆优化,顾名思义,就是用堆进行优化。我们通过学习朴素DIJ算法,明白DIJ算法的实现需要从头到尾扫一遍点找出最小的点然后进行松弛。这个扫描操作就是坑害朴素DIJ算法时间复杂度的罪魁祸首。所以我们使用小根堆,用优先队列来维护这个“最小的点”。从而大大减少DIJ算法的时间复杂度。 堆优化的代码实现 说起来容易,做起来难。 我们明白了上述的大体思路之后,就可以动手写这个代码,但是我们发现这个代码有很多细节问题没有处理。 首先,我们需要往优先队列中push最短路长度,但是它一旦入队,就会被优先队列自动维护离开原来的位置,换言之,我们无法再把它与它原来的点对应上,也就是说没有办法形成点的编号到点权的映射。 我们用pair解决这个问题。 pair是C++自带的二元组。我们可以把它理解成一个有两个元素的结构体。更刺激的是,这个二元组有自带的排序方式:以第一关键字为关键字,再以第二关键字为关键字进行排序。所以,我们用二元组的first位存距离,second位存编号即可。 然后我们发现裸的优先队列其实是大根堆,我们如何让它变成小根堆呢? 有两种方法,第一种是把第一关键字取相反数,取出来的时候再取相反数。第二种是重新定义优先队列:

Why does Dijkstra's algorithm use decrease-key?

巧了我就是萌 提交于 2019-11-28 02:48:16
Dijkstra's algorithm was taught to me was as follows while pqueue is not empty: distance, node = pqueue.delete_min() if node has been visited: continue else: mark node as visited if node == target: break for each neighbor of node: pqueue.insert(distance + distance_to_neighbor, neighbor) But I've been doing some reading regarding the algorithm, and a lot of versions I see use decrease-key as opposed to insert. Why is this, and what are the differences between the two approaches? The reason for using decrease-key rather than reinserting nodes is to keep the number of nodes in the priority queue

POJ - 2112 Optimal Milking (dijkstra + 二分 + 最大流Dinic)

做~自己de王妃 提交于 2019-11-28 01:49:54
(点击此处查看原题) 题目分析 题意: 在一个农场中有k台挤奶器和c只奶牛,每个挤奶器最多只能为m只奶牛挤奶,每个挤奶器和奶牛都视为一个点,将编号1~k记为挤奶器的位置,编号k+1~k+c记为奶牛的位置,奶牛只能在这k+c个位置之间移动,输入将给出每个位置和其余k+c个位置的之间道路距离,其中0代表无法到达 问让所有奶牛进行挤奶的情况下(也就是让每头奶牛都走到一个挤奶器的位置上去,而且这个挤奶器上的奶牛不得超过m个),求c只奶牛中走的最远的奶牛的最小移动总距离。 思路: 首先思考到这题目要二分答案,因为移动最远的奶牛的移动总距离越大,就越有可能满足要求 然后我们用c次dijkstra求出每个奶牛到所有挤奶器的最近距离,再根据我们二分的奶牛移动最远距离,限制了每个奶牛可以到达的挤奶器 随后我们就要判断这种情况下是否所有奶牛都可以到达一个挤奶器,而且每个挤奶器上的奶牛不超过m个,此时就是一个明显的求最大流问题了,建图如下: 1)由源点向每个奶牛建一条容量为1的边 2)由每个挤奶器向汇点建一条容量为m的边 3)由每个奶牛向其可以到达的所有挤奶器建一条容量为inf的边 最后,我们跑出这个图的最大流,如果最大流等于c,说明当前的情况是满足的,需要尝试更小的最远的距离;如果最大流不等于c,说明当前的最远距离太小了,以至于有奶牛无法到达挤奶器,需要尝试更大的最远距离。 代码区 #include

How to optimize Dijkstra algorithm for a single shortest path between 2 nodes?

喜欢而已 提交于 2019-11-28 01:19:24
问题 I was trying to understand this implementation in C of the Dijkstra algorithm and at the same time modify it so that only the shortest path between 2 specific nodes (source and destination) is found. However, I don't know exactly what do to. The way I see it, there's nothing much to do, I can't seem to change d[] or prev[] cause those arrays aggregate some important data for the shortest path calculation. The only thing I can think of is stopping the algorithm when the path is found, that is,

Performance of Dijkstra's algorithm implementation

早过忘川 提交于 2019-11-28 00:59:05
问题 Below is an implementation of Dijkstra's algorithm I wrote from the pseudocode in the Wikipedia article. For a graph with about 40 000 nodes and 80 000 edges, it takes 3 or 4 minutes to run. Is that anything like the right order of magnitude? If not, what's wrong with my implementation? struct DijkstraVertex { int index; vector<int> adj; vector<double> weights; double dist; int prev; bool opt; DijkstraVertex(int vertexIndex, vector<int> adjacentVertices, vector<double> edgeWeights) { index =