If std::vector<vector<pair<int,int> > > v(n)
represents the adjacency list of the graph with pair<int,int>
is the {vertex,weight}
pair, I tried to implement the algorithm the following way:
while (true)
{
long long yo = LLONG_MAX;
int ind = -1;
for (int i = 0; i < n; ++i)
{
if (ans[i] < yo && !v[i].empty())
{
ind = i;
yo = ans[i];
}
}
if (ind == -1)
break;
for (int i = 0; i < v[ind].size(); ++i)
{
if (ans[v[ind][i].first] > ans[ind] + v[ind][i].second)
ans[v[ind][i].first] = ans[ind] + v[ind][i].second;
v[ind].erase(v[ind].begin() + i);
}
}
Where ans[i]
stores the shortest paths which is initialised as {LLONG_MAX,...0,...LLONG_MAX}
, 0
being the source. Since this is the first time I tried implementing it, is there a better way to implement using the vectors/list in stl (in terms of time/space complexity maybe)?
Current approach has logical bug ( modifying the vector while iterating it ). Also Complexity wise it seems very bad as well, due to redundant while loop to get the new minimum distance node each time and un-necessary erase operation, which is heavy in vector due to shifting of the entire adjacency list.
I would recommend using a priority queue < min heap >, which is much cleaner and have a complexity of Elog(N), where E is no. of edges and N no. of node in graph. I am just copying pasting one of my old codes with comments.
#define P first
#define Q second
typedef long long LL ;
typedef pair < LL , int > li ;
typedef pair < int , LL > il ;
dist[N] = {INT_MAX} ; // array containing the distance to each node from source node
vector < il > adj [100010] ; // adjacency list with (node, distance) pair
void dijkstra( int s ){ // s is the source node
priority_queue < li , vector < li > , greater < li > > pq; // priortiy queue with a pair <long, int> as the data , using vector as underlying data structure and std:greater comparator
dist [s] = 0;
pq.push( li( dist[s], s) );
while( !pq.empty() ){
li u = pq.top() ; pq.pop() ; // u.P = current minimum distance of node , u.Q = current node on top of the heap
if( dist[u.Q] == u.P )
for( int i = 0 ; i < adj[u.Q].size() ; i++){
il v = adj[u.Q][i] ;
if( dist[v.P] > u.P + v.Q ){
dist[v.P] = u.P + v.Q ;
pq.push( li(dis[v.P] ,v.P ));
}
}
}
If you have any questions, feel free to ask in comments.
Some ways to optimize Dijkstra:
Theoretically, Dijkstra can be optimized to O(E + VlogV) with Fibonacci heap. But in practice it works slower.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.