Dijkstra algorithm implementation with adjacency list I've implemented the Dijkstra Algorithm to obtain the minimum paths between a source node and every other.  

#include &lt;bits/stdc++.h&gt;

typedef std::vector&lt;std::list&lt;int&gt;&gt; AdjacencyList;
typedef std::vector&lt;std::vector&lt;int&gt;&gt; Weights;

std::vector&lt;int&gt; dijkstra(AdjacencyList &amp;adj, Weights weights, int src) {
    int n = adj.size();

    std::vector&lt;int&gt; prev(n, -1);
    std::vector&lt;int&gt; dist (n, INT_MAX);
    std::vector&lt;bool&gt; visited(n, false);

    auto comp = [&amp;dist](const int&amp; lhs, const int&amp; rhs) -&gt; bool { return dist[lhs] &gt; dist[rhs]; };
    std::priority_queue&lt;int, std::vector&lt;int&gt;, decltype(comp)&gt; candidates(comp);

    candidates.push(src);
    dist[src] = 0;
    for (int j = 0; j &lt; n - 1; ++j) {
        int next = candidates.top();
        candidates.pop();
        visited[next] = true;
        for(std::list&lt;int&gt;::const_iterator it = adj[next].begin(); it != adj[next].end(); it++) {
            int neighbor = *it;
            if (!visited[neighbor] &amp;&amp; (dist[next] + weights[next][neighbor] &lt; dist[neighbor])) {
                dist[neighbor] = dist[next] + weights[next][neighbor];
                prev[neighbor] = next;
                candidates.push(neighbor);
            }
        }
    }
    return prev;
}


I wrote this code to practice but also to be used at competition contests. So, i want this to be simple, clear and efficient at the same time (without losing so much readability). Any advices?
Advice 1

int n = adj.size();


I would change int to size_t, since it counts size that may not be negative.

Advice 2

for (int j = 0; j &lt; n - 1; ++j) {
    ...
}


I would change it to 

while (!candidates.empty()) {

}


This omits some unnecessary computation in case the graph is disconnected.

Advice 3

candidates may be renamed to open, open_list or frontier; that is more or less conventional naming for that data structure in pathfinding community.

Advice 4

I would change typedef std::vector&lt;std::vector&lt;int&gt;&gt; Weights; to typedef std::unordered_map&lt;int, std::unordered_map&lt;int, size_t&gt;&gt; Weights;. This makes filling the edge weights much more easier; especially on sparse graphs:

w[a][b1] = 3;
w[a][b2] = 1;
...


Advice 5

if (!visited[neighbor] &amp;&amp; (dist[next] + weights[next][neighbor] &lt; dist[neighbor])) {
    ...
}


This condition is a bug. It should be 

if (dist[neighbor] == INT_MAX || (dist[next] + weights[next][neighbor] &lt; dist[neighbor])) {
    ...
}


(Note dist[neighbor] == INT_MAX and || instead of &amp;&amp;. You can try changing || to &amp;&amp; and see its effect here.)