Problem:
Single Source Shortest Path II
For a given weighted graph $G = (V, E)$, find the shortest path from a source to each vertex. For each vertex $u$, print the total weight of edges on the shortest path from vertex $0$ to $u$.
Input
In the first line, an integer $n$ denoting the number of vertices in $G$ is given. In the following $n$ lines, adjacency lists for each vertex $u$ are respectively given in the following format:
$u$ $k$ $v_1$ $c_1$ $v_2$ $c_2$ ... $v_k$ $c_k$
Vertices in $G$ are named with IDs $0, 1, ..., n-1$. $u$ is ID of the target vertex and $k$ denotes its degree. $v_i (i = 1, 2, ... k)$ denote IDs of vertices adjacent to $u$ and $c_i$ denotes the weight of a directed edge connecting $u$ and $v_i$ (from $u$ to $v_i$).
Output
For each vertex, print its ID and the distance separated by a space character in a line respectively. Print in order of vertex IDs.
Constraints
$1 \leq n \leq 10,000$
$0 \leq c_i \leq 100,000$
$|E| < 500,000$
All vertices are reachable from vertex $0$
Sample Input 1
5
0 3 2 3 3 1 1 2
1 2 0 2 3 4
2 3 0 3 3 1 4 1
3 4 2 1 0 1 1 4 4 3
4 2 2 1 3 3
Sample Output 1
0 0
1 2
2 2
3 1
4 3
Reference
Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Submitted solutions:

code_snippet: #include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
static const int MAX = 10000;
static const int INFTY = (1<<20);
static const int WHITE = 0;
static const int GRAY = 1;
static const int BLACK = 2;

int n;
vector<pair<int,int>> adj[MAX];

void dijkstra(){
    int color[MAX],d[MAX];
    priority_queue<pair<int,int>> PQ;
    
    for(int i = 0 ; i < n; i++){
        d[i] = INFTY;
        color[i] = WHITE;
    }

    d[0] = 0;
    color[0] = GRAY;
    PQ.push(make_pair(0,0));

    while(!PQ.empty()){
        pair<int,int> f = PQ.top();
        PQ.pop();
        int u = f.second;
        
        color[u] = BLACK;

        if(d[u] < f.first * (-1)) continue;//PQは降順にソート

        for(int i = 0 ; i< adj[u].size(); i++){
            int v = adj[u][i].first;
            int c = adj[u][i].second;
            if(d[v] > d[u] + c){
                d[v] = d[u] + c;
                PQ.push(make_pair( (-1) * d[v], v));
                color[v] = GRAY;
            }

        }

    }

    for(int i = 0; i < n; i++){
        cout << i << " " << d[i] << endl;
    }
    
}

int main(){
    int k,u,v,c;

    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> u >> k;
        for(int j = 0; j < k; j++){
            cin >> v >> c;
            adj[u].push_back(make_pair(v,c));
        }
    }

    dijkstra();
}
accuracy: 1
time_ms: 110
memory_kb: 8240
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
const int INF = 100000000;

struct priority_lesser {
    bool operator()(const pair<int,int>& a, const pair<int,int>& b) const {
        return a.second > b.second; // second が小さい方を優先
    }
};

int main()
{
    int n;
    cin >> n;
    //pair(v, c)を保存
    vector<vector<pair<int, int>>> adj(n);
    rep(i, n)
    {
        int u, k;
        cin >> u >> k;
        adj[u] = vector<pair<int, int>>(k);
        rep(j, k)
        {
            cin >> adj[u][j].first;
            cin >> adj[u][j].second;
        }
    }

    //-1:到達不可, 0:隣接未訪問, 1:訪問済み
    vector<int> state(n, -1);
    priority_queue<pair<int, int>, vector<pair<int, int>>, priority_lesser> pq;
    vector<int> d(n, INF);

    state[0] = 0;
    d[0] = 0;
    pq.push({0, 0});
    
    while(true)
    {
        //未訪問の頂点につながる辺がtopに来るまでpopする
        while(state[pq.top().first] == 1 && !pq.empty())
            pq.pop();

        if(pq.empty())
            break;

        int u = pq.top().first;
        state[u] = 1;
        pq.pop();

        for(pair<int, int> uv : adj[u]) if(state[uv.first] != 1)
        {
            int v = uv.first;
            if(state[v] == -1)
                state[v] = 0;

            pair<int, int> path = {v, d[u] + uv.second};
            if(path.second < d[v])
            {
                d[v] = path.second;
                pq.push(path);
            }
        }
    }

    rep(i, n)
    {
        cout << i << " " << d[i] << endl;
    }
}
accuracy: 1
time_ms: 110
memory_kb: 7180
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
const int INF = 100000000;

struct priority_lesser {
    bool operator()(const pair<int,int>& a, const pair<int,int>& b) const {
        return a.second > b.second; // second が小さい方を優先
    }
};

int main()
{
    int n;
    cin >> n;
    //pair(v, c)を保存
    vector<vector<pair<int, int>>> adj(n);
    rep(i, n)
    {
        int u, k;
        cin >> u >> k;
        adj[u] = vector<pair<int, int>>(k);
        rep(j, k)
        {
            cin >> adj[u][j].first;
            cin >> adj[u][j].second;
        }
    }

    //-1:到達不可, 0:隣接未訪問, 1:訪問済み
    vector<int> state(n, -1);
    priority_queue<pair<int, int>, vector<pair<int, int>>, priority_lesser> pq;
    vector<int> d(n, INF);

    state[0] = 0;
    d[0] = 0;
    pq.push({0, 0});
    
    while(true)
    {
        //未訪問の頂点につながる辺がtopに来るまでpopする
        while(state[pq.top().first] == 1 && !pq.empty())
            pq.pop();

        if(pq.empty())
            break;

        int u = pq.top().first;
        state[u] = 1;
        pq.pop();
        for(pair<int, int> uv : adj[u]) if(state[uv.first] != 1)
        {
            int v = uv.first;
            if(state[v] == -1)
                state[v] = 0;

            pair<int, int> path = {v, d[u] + uv.second};
            if(path.second < d[v])
            {
                d[v] = path.second;
                pq.push(path);
            }
        }
    }

    rep(i, n)
    {
        cout << i << " " << d[i] << endl;
    }
}
accuracy: 1
time_ms: 110
memory_kb: 7484
final_rank: 4

code_snippet: #include <bits/stdc++.h>
#include <queue>
using namespace std;
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
const int INF = 100000000;

struct priority_lesser {
    bool operator()(const pair<int,int>& a, const pair<int,int>& b) const {
        return a.second > b.second; // second が小さい方を優先
    }
};

int main()
{
    int n;
    cin >> n;
    //pair(v, c)を保存
    vector<vector<pair<int, int>>> adj(n);
    rep(i, n)
    {
        int u, k;
        cin >> u >> k;
        adj[u] = vector<pair<int, int>>(k);
        rep(j, k)
        {
            cin >> adj[u][j].first;
            cin >> adj[u][j].second;
        }
    }

    //-1:到達不可, 0:隣接未訪問, 1:訪問済み
    vector<int> state(n, -1);
    priority_queue<pair<int, int>, vector<pair<int, int>>, priority_lesser> pq;
    vector<int> d(n, INF);

    state[0] = 1;
    d[0] = 0;
    rep(i, adj[0].size())
        pq.push(adj[0][i]);
    
    while(true)
    {
        //未訪問の頂点につながる辺がtopに来るまでpopする
        while(state[pq.top().first] == 1 && !pq.empty())
            pq.pop();

        if(pq.empty())
            break;

        int u = pq.top().first;
        d[u] = pq.top().second;
        state[u] = 1;
        pq.pop();
        for(pair<int, int> uv : adj[u]) if(state[uv.first] != 1)
        {
            if(state[uv.first] == -1)
                state[uv.first] = 0;

            pair<int, int> path = pair(uv.first, d[u] + uv.second);
            pq.push(path);
        }
    }

    rep(i, n)
    {
        cout << i << " " << d[i] << endl;
    }
}
accuracy: 1
time_ms: 100
memory_kb: 10560
final_rank: 15

code_snippet: #include <cstdio>
#include <vector>
#include <iostream>
#include <queue>
using namespace std;
#define INF 0x3f3f3f
#define NIL -1
const int ma=10000;
int n; 
int color[ma];
int d[ma];
vector<pair<int,int>> adj[ma];
void dijkstra(){
    priority_queue<pair<int,int>> PQ;//优先级队列默认比较前一个值，所以应该是前一个值是距离，后一个值是顶点，而且要是最小堆，可以取巧，存入相反数
    for(int i=0;i<n;i++){
        color[i]=0;
        d[i]=INF;
    }
    d[0]=0;
    PQ.push(make_pair(0,0));
    while(!PQ.empty()){
        pair<int,int> u=PQ.top();
        PQ.pop();
        color[u.second]=2;
        if(d[u.second]<u.first*(-1)){//比较现在u的成本和历史u的成本，因为下面可能会把同一个在不同时间不同的距离的值加进去，我们只要等于历史的那个u
            continue;
        }
        for(int i=0;i<(int)adj[u.second].size();i++){//
            int v=adj[u.second][i].first;//相邻结点
            if(color[v]!=2){
                if(d[u.second]+adj[u.second][i].second<d[v]){
                    d[v]=d[u.second]+adj[u.second][i].second;
                    color[v]=1;
                    PQ.push(make_pair((-1)*d[v],adj[u.second][i].first));
                }
            }
        }
    }
}
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        int m,k;
        scanf("%d %d",&m,&k);
        for(int j=0;j<k;j++){
            int c,d;
            scanf("%d %d",&c,&d);
            adj[m].push_back(make_pair(c,d));
        }
    }
    dijkstra();
    for(int i=0;i<n;i++){
        printf("%d %d\n",i,d[i]);
    }
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 8640
final_rank: 2

code_snippet: #pragma region Macros
#include <bits/stdc++.h>

#include <atcoder/all>
using namespace std;
using namespace atcoder;
using lint = long long;
using mint = modint998244353;
using ull = unsigned long long;
using ld = long double;
using int128 = __int128_t;
#define all(x) (x).begin(), (x).end()
#define EPS 1e-8
#define uniqv(v) v.erase(unique(all(v)), v.end())
#define OVERLOAD_REP(_1, _2, _3, name, ...) name
#define REP1(i, n) for (auto i = std::decay_t<decltype(n)>{}; (i) != (n); ++(i))
#define REP2(i, l, r) for (auto i = (l); (i) != (r); ++(i))
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
#define log(x) cout << x << endl
#define logfixed(x) cout << fixed << setprecision(10) << x << endl;
#define logy(bool)             \
    if (bool) {                \
        cout << "Yes" << endl; \
    } else {                   \
        cout << "No" << endl;  \
    }

ostream &operator<<(ostream &dest, __int128_t value) {
    ostream::sentry s(dest);
    if (s) {
        __uint128_t tmp = value < 0 ? -value : value;
        char buffer[128];
        char *d = end(buffer);
        do {
            --d;
            *d = "0123456789"[tmp % 10];
            tmp /= 10;
        } while (tmp != 0);
        if (value < 0) {
            --d;
            *d = '-';
        }
        int len = end(buffer) - d;
        if (dest.rdbuf()->sputn(d, len) != len) {
            dest.setstate(ios_base::badbit);
        }
    }
    return dest;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    for (int i = 0; i < (int)v.size(); i++) {
        os << v[i] << (i + 1 != (int)v.size() ? " " : "");
    }
    return os;
}

template <typename T>
ostream &operator<<(ostream &os, const set<T> &set_var) {
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end()) os << " ";
        itr--;
    }
    return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << itr->first << " -> " << itr->second << "\n";
    }
    return os;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &pair_var) {
    os << "(" << pair_var.first << ", " << pair_var.second << ")";
    return os;
}

void out() { cout << '\n'; }
template <class T, class... Ts>
void out(const T &a, const Ts &...b) {
    cout << a;
    (cout << ... << (cout << ' ', b));
    cout << '\n';
}

template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
    for (T &in : v) is >> in;
    return is;
}

inline void in(void) { return; }
template <typename First, typename... Rest>
void in(First &first, Rest &...rest) {
    cin >> first;
    in(rest...);
    return;
}

template <typename T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <typename T>
bool chmin(T &a, const T &b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

vector<lint> dx8 = {1, 1, 0, -1, -1, -1, 0, 1};
vector<lint> dy8 = {0, 1, 1, 1, 0, -1, -1, -1};
vector<lint> dx4 = {1, 0, -1, 0};
vector<lint> dy4 = {0, 1, 0, -1};

#pragma endregion

template <class T>
class Dijkstra {
   private:
    vector<vector<pair<int, T>>> g;
    vector<T> dist;
    vector<int> prev;
    int n;

   public:
    Dijkstra(vector<vector<pair<int, T>>> _g, int start = 0) {
        g = _g;
        n = g.size();
        dist.assign(n, -1);
        prev.assign(n, -1);
        vector<bool> fin(n, false);
        priority_queue<tuple<T, int, int>, vector<tuple<T, int, int>>, greater<tuple<T, int, int>>> q;
        dist[start] = 0;
        q.emplace(0, start, -1);
        while (!q.empty()) {
            int cur = get<1>(q.top());
            int pre = get<2>(q.top());
            q.pop();
            if (fin[cur]) continue;
            fin[cur] = true;
            prev[cur] = pre;
            for (auto p : g[cur]) {
                int nex = p.first;
                int weight = p.second;
                if (dist[nex] == -1 or dist[nex] > dist[cur] + weight) {
                    dist[nex] = dist[cur] + weight;
                    q.emplace(dist[nex], nex, cur);
                }
            }
        }
    }

    void rebuild(int start) {
        dist.assign(n, -1);
        prev.assign(n, -1);
        vector<bool> fin(n, false);
        priority_queue<tuple<T, int, int>, vector<tuple<T, int, int>>, greater<tuple<T, int, int>>> q;
        dist[start] = 0;
        q.emplace(0, start, -1);
        while (!q.empty()) {
            int cur = get<1>(q.top());
            int pre = get<2>(q.top());
            q.pop();
            if (fin[cur]) continue;
            fin[cur] = true;
            prev[cur] = pre;
            for (auto p : g[cur]) {
                int nex = p.first;
                int weight = p.second;
                if (dist[nex] == -1 or dist[nex] > dist[cur] + weight) {
                    dist[nex] = dist[cur] + weight;
                    q.emplace(dist[nex], nex, cur);
                }
            }
        }
    }

    vector<T> get_dist() {
        return dist;
    }

    T get_dist(int t) {
        return dist[t];
    }

    vector<int> get_route(int t) {
        vector<int> ret;
        if (dist[t] == -1) return ret;

        int cur = t;
        while (cur != -1) {
            ret.emplace_back(cur);
            cur = prev[cur];
        }
        reverse(ret.begin(), ret.end());
        return ret;
    }
};

int main() {
    cin.tie(0)->sync_with_stdio(0);

    int n;
    in(n);
    vector<vector<pair<int, lint>>> g(n);
    rep(i, n) {
        int u, k;
        in(u, k);
        rep(j, k) {
            int v, c;
            in(v, c);
            g[u].emplace_back(v, c);
        }
    }

    Dijkstra<lint> d(g);
    rep(i, n) {
        out(i, d.get_dist(i));
    }
}
accuracy: 1
time_ms: 30
memory_kb: 28032
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define rep2(i, s, n) for (ll i = (s); i < (n); i++)


// vectorを出力する
void vecprint(vector<ll> vec) {
    rep(i, vec.size()) {
        cout << vec[i] << endl;
    }
}
void newvecprint(vector<ll> vec) {
    rep(i, vec.size()) {
        cout << vec[i] << " ";
    }
    cout << endl;
}

// 最大か最小を求める
ll minval(vector<ll> vec) {
    return *min_element(begin(vec), end(vec));
}
ll maxval(vector<ll> vec) {
    return *max_element(begin(vec), end(vec));
}

vector<string> color;
vector<ll> d;
vector<ll> p;
vector<pair<ll, ll>> adj[10000];
ll INFTY = 1000000;
priority_queue<pair<ll, ll>> PQ;

// ヒープによるダイクストラ法
void dijkstra() {
    rep(u, color.size()) {
        color[u] = "white";
        d[u] = INFTY;
    }
    d[0] = 0;
    PQ.push({0, 0});
    color[0] = "gray";
    while (PQ.size() != 0) {
        pair<ll, ll> f = PQ.top();
        PQ.pop();
        ll u = f.second;
        color[u] = "black";
        if (d[u] < f.first * (-1)) {
            continue;
        }
        for (int j = 0; j < adj[u].size(); j++) {
            ll v = adj[u][j].first;
            if (color[v] == "black") {
                continue;
            }
            if (d[v] > d[u] + adj[u][j].second) {
                d[v] = d[u] + adj[u][j].second;
                PQ.push(make_pair(d[v] * (-1), v));
                color[v] = "gray";
            }
        }
    }
    rep(i,d.size()) {
        cout << i << " " << (d[i] == INFTY ? -1 : d[i]) << endl;
    }
}

void solve() {
    ll k, u, v, c, n;
    cin >> n;
    color.resize(n);
    d.resize(n);
    p.resize(n);
    rep(i,n) {
        cin >> u >> k;
        rep(j, k) {
            cin >> v >> c;
            adj[u].push_back(make_pair(v,c));
        }
    }
    dijkstra();

    return;
}

int main() {
    solve();
    return 0;
}
accuracy: 1
time_ms: 90
memory_kb: 12672
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i=0; i<n; i++)
using P = pair<int,int>;

struct Edge {
    int to, cost;
    Edge() {}
    Edge(int to, int cost) : to(to), cost(cost) {}
};

int main()
{
    int n;
    cin >> n;
    vector<vector<Edge>> g(n);
    rep(i,n) {
        int u,k;
        cin >> u >> k;
        rep(j,k) {
            int v,c;
            cin >> v >> c;
            g[u].emplace_back(v,c);
        }
    }

    const int INF = 1e9;
    priority_queue<P,vector<P>,greater<P>> q;
    vector<int> dist(n,INF);
    dist[0] = 0;
    q.emplace(0,0);

    while (!q.empty()) {
        auto [c, v] = q.top(); q.pop();
        if (dist[v] != c) continue;
        for (Edge e : g[v]) {
            int nd = e.cost + dist[v];
            if (nd >= dist[e.to]) continue;
            dist[e.to] = nd;
            q.emplace(nd,e.to);
        }
    }

    rep(i,n) cout << i << ' ' << dist[i] << '\n';
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 8264
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int WHITE = 0;
const int GRAY = 1;
const int BLACK = 2;
const int INFTY = 1<<30;
int n;

const int MAX = 10000;

int d[MAX], color[MAX];

vector<pair<int, int>> M[MAX];

void dijkstra()
{
    for (int i = 0; i < n; i++)
    {
        d[i] = INFTY;
        color[i] = WHITE;
    }

    d[0] = 0;
    priority_queue<pair<int, int>> PQ;
    PQ.push(make_pair(0, 0));

    while (!PQ.empty())
    {
        pair<int, int> f = PQ.top(); PQ.pop();
        int u = f.second;

        color[u] = BLACK;

        if (d[u] < f.first*(-1)) continue;

        for (int i = 0; i < M[u].size(); i++)
        {
            int v = M[u][i].first;
            if (color[v] != BLACK && d[v] > d[u] + M[u][i].second)
            {
                d[v] = M[u][i].second + d[u];
                color[v] = GRAY;
                PQ.push(make_pair(d[v] * -1, v));
            }
        }
    } 
}

int main()
{
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        int u, k;
        cin >> u >> k;
        for (int j = 0; j < k; j++)
        {
            int v, c;
            cin >> v >> c;
            M[u].push_back(make_pair(v, c));
        }
    }

    dijkstra();

    for (int i = 0; i < n; i++)
    {
        cout << i << " " << d[i] << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 8464
final_rank: 13

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

static const int INFTY = 1<<20;
static const int N_MAX = 10000;

static const int NIL = -1;

static const int WHITE = 0; // Not visited (initial state)
static const int GRAY = 1;  // Candidate of next visit
static const int BLACK = 2; // Visited

// weight of all edges
// int W[N_MAX][N_MAX];
vector<pair<int, int>> W[N_MAX];

// Visiting state
int colors[N_MAX];

// minimum cost to connect
int d[N_MAX];
auto compare = [](pair<int, int> a, pair<int, int> b) {
    return a.second > b.second;
};
priority_queue<
    pair<int, int>,
    vector<pair<int, int>>,
    decltype(compare)
> PQ(compare);

// parent
int p[N_MAX];

/*
Find the minimum cost to go to all nodes from node `start`.
`n` is the number of total nodes
*/
void dijkstra(int start, int n){

    d[start] = 0;
    PQ.push(make_pair(start, 0));
    // int u;
    pair<int, int> u;
    while(!(PQ.empty())) {
        // Find the node u
        // that we can go with minimum cost from Minimum Path
        u = PQ.top();
        PQ.pop();

        // It may not be the minimum path
        // because PQ has the path which is not minimum.
        if( d[u.first] < u.second) continue;

        colors[u.first] = BLACK;

        // d[*]の更新
        // uと隣接するvにおいて、d[u] + weight(u, v)の値を
        // ヒープにpushする
        for(
            int i=0;
            i < W[u.first].size();
            i++
        ){
            // adjacent node of u.
            pair<int, int> v = W[u.first][i];
            if(colors[v.first] != BLACK){
                if(
                    d[u.first] + v.second < d[v.first]
                ){
                    d[v.first] = d[u.first] + v.second;
                    colors[v.first] = GRAY;
                    PQ.push(make_pair(v.first, d[v.first]));
                }
            }
        }
    }
}

int main () {

    // Read data
    int n;
    cin >> n;
    int from, to, weight, n_edges;
    // for(int i=0; i<n; i++) {
    //     for(int j=0; j<n; j++){
    //         W[i][j] = NIL;
    //     }
    // }
    for(int i=0; i<n; i++){
        cin >> from >> n_edges;
        for(int j=0; j<n_edges; j++) {
            scanf("%d %d", &to, &weight);
            // W[from][to] = weight;
            W[from].push_back(make_pair(to, weight));
        }
    }

    // for(int i=0; i<n; i++) {
    //     for(int j=0; j<n; j++){
    //         // W[i][j] = NIL;
    //         cout << W[i][j] << " ";
    //     }
    //     cout << endl;
    // }

    // initialize
    for(int i=0; i<n; i++){
        colors[i] = WHITE;
        d[i] = INFTY;
        p[i] = NIL;
    }

    dijkstra(0, n);
    
    for(int i=0; i<n; i++){
        cout << i << " " << d[i] << endl;
    }

    return 0;

}
accuracy: 1
time_ms: 40
memory_kb: 8396
final_rank: 1

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef pair<int,int> PII;
const int N=1e4+5;
const int INF=2e9;
vector<int>E[N],W[N];
int n,dis[N];
struct Comp{
    bool operator()(PII a,PII b){
        return a.first>b.first;
    }
};  
void solve(){
    cin>>n;
    for(int i=0;i<n;i++){
        int u,k;cin>>u>>k;
        for(int j=0;j<k;j++){
            int v,w;cin>>v>>w;
            E[u].push_back(v);
            W[u].push_back(w);
        }
    }
    priority_queue<PII,vector<PII>,Comp>q;
    q.push({0,0});
    for(int i=0;i<n;i++){
        dis[i]=INF;
    }
    while(!q.empty()){
        PII p=q.top();q.pop();
        int d=p.first,u=p.second;
        if(dis[u]!=INF) continue;
        dis[u]=d;
        int len=E[u].size();
        for(int i=0;i<len;i++){
            int v=E[u][i],w=W[u][i];
            if(dis[v]!=INF) continue;
            q.push({d+w,v});
        }
    }
    for(int i=0;i<n;i++){
        cout<<i<<" "<<dis[i]<<endl;
    }
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0),cout.tie(0);
    int T=1;
    // cin>>T;
    for(int t=1;t<=T;t++){
        solve();
    }
    return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 18020
final_rank: 17

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <utility> // for std::pair

static const int INFTY = (1 << 21);

int n;
std::vector<std::vector<std::pair<int, int>>> adj; // adjacency list
std::vector<int> d; // distance array

void dijkstra() {
    d.assign(n, INFTY); // initialize all distances
    d[0] = 0;

    std::priority_queue<std::pair<int, int>,
                        std::vector<std::pair<int, int>>,
                        std::greater<std::pair<int, int>>> pq;

    pq.push(std::make_pair(0, 0)); // (distance, vertex)

    while (!pq.empty()) {
        std::pair<int, int> top = pq.top();
        pq.pop();

        int dist_u = top.first;
        int u = top.second;

        if (dist_u > d[u]) continue; // skip outdated entry

        for (size_t i = 0; i < adj[u].size(); i++) {
            std::pair<int, int> edge = adj[u][i];
            int v = edge.first;
            int cost = edge.second;

            if (d[u] + cost < d[v]) {
                d[v] = d[u] + cost;
                pq.push(std::make_pair(d[v], v));
            }
        }
    }

    for (int i = 0; i < n; i++) {
        std::cout << i << " " << d[i] << std::endl;
    }
}

int main() {
    int k, u, v, c;

    std::cin >> n;
    adj.resize(n); // allocate exactly n nodes

    for (int i = 0; i < n; i++) {
        std::cin >> u >> k;
        for (int j = 0; j < k; j++) {
            std::cin >> v >> c;
            adj[u].emplace_back(v, c);
        }
    }

    dijkstra();
}
accuracy: 1
time_ms: 110
memory_kb: 8332
final_rank: 12

code_snippet: #include <iostream>
#include <vector>
#include <queue>
#include <utility> // for std::pair

// global variables
static const int N = 1000;
static const int INFTY = (1 << 21);

int n;
std::vector<std::pair<int, int>> adj[N]; // adjacency list: [(neighbor, cost),...]
int d[N];

// algorithm
void dijkstra() {
    std::priority_queue<std::pair<int, int>,
                        std::vector<std::pair<int, int>>,
                        std::greater<std::pair<int, int>>> pq;

    for (int i = 0; i < n; i++) {
        d[i] = INFTY;
    }
    d[0] = 0;
    pq.push(std::make_pair(0, 0)); // (distance, vertex)

    while (!pq.empty()) {
        std::pair<int, int> top = pq.top();
        pq.pop();

        int dist_u = top.first;
        int u = top.second;

        if (dist_u > d[u]) continue; // outdated entry

        for (size_t i = 0; i < adj[u].size(); i++) {
            std::pair<int, int> edge = adj[u][i];
            int v = edge.first;
            int cost = edge.second;

            if (d[u] + cost < d[v]) {
                d[v] = d[u] + cost;
                pq.push(std::make_pair(d[v], v));
            }
        }
    }

    // Output result
    for (int i = 0; i < n; i++) {
        std::cout << i << " " << d[i] << std::endl;
    }
}

int main() {
    int k, u, v, c;

    std::cin >> n;
    for (int i = 0; i < n; i++) {
        std::cin >> u >> k;
        for (int j = 0; j < k; j++) {
            std::cin >> v >> c;
            adj[u].emplace_back(v, c);
        }
    }

    dijkstra();
}
accuracy: 0.875
time_ms: 110
memory_kb: 8244
final_rank: 20

code_snippet: #include <iostream>
#include <string>
#include <map>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <limits.h>
using namespace std;

enum VisitColor {
    WHITE,
    GRAY,
    BLACK
};

int main() {
    int n;
    int o; // 出次数(隣接点の数)
    int p; // 頂点の番号
    //int M[100][100];
    vector<vector<pair<int, int>>>M; // 隣接する点の番号・辺の重みをMに点毎に格納する
    M.resize(10000);
    priority_queue<pair<int, int>> PQ; // キューを構成するペアの1つ目は、点への最短距離 2つ目は点の番号
    int color[10000]; // 各点の訪問状態

    int d[10000]; // 始点から各点への最短距離を格納する配列

    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> p >> o;
        for (int j = 0; j < o; j++) {
            pair<int, int> tmpPair;

            // 隣接点番号, 隣接点への辺の重みを入力
            cin >> tmpPair.first >> tmpPair.second;
            M[i].push_back(tmpPair); // 隣接リストを構成する
        }

        d[i] = INT_MAX; // 最終的に最小値が入るため、大きな値に初期化
        color[i] = WHITE; // 全ての点を未訪問に初期化
    }

    // 0番目の点から探索をスタートする
    d[0] = 0; // 最初は、始点から始点に探索すると考える。始点から始点のコストは0
    color[0] = GRAY;

    // プライオリティーキューの初期化
    PQ.push(make_pair(0, 0)); //始点への最短距離, 始点番号

    // PQが空になるまで続く
    // PQには、最短経路木Tと、Tに隣接する点への距離と点の番号が格納されている。
    // PQが空→PQのトップには、最短経路木Tと、Tに隣接する点の中で、最短距離をとる点への距離と、その点の番号が格納されているが、これが全てなくなると、全ての点への最短距離が確定したことになる
    while (!PQ.empty()) {
        pair<int, int> minPair = PQ.top();
        PQ.pop();

        int u = minPair.second; // 最短経路木に隣接する点の中で最短距離をとる点を起点として探索を行う
        color[u] = BLACK; // 訪問済み

        //if(d[u] < minPair.first * (-1)) continue;

        // uを起点として隣接点へ探索を行う
        for (int i = 0; i < M[u].size(); i++) {
            int v = M[u][i].first;

            // vへ未訪問
            if (color[v] != BLACK) {
                // vへの最短距離更新
                if (d[v] > d[u] + M[u][i].second) { // ここでアウト
                    d[v] = d[u] + M[u][i].second;
                    color[v] = GRAY; // 探索済み

                    // キュー更新
                    PQ.push(make_pair(d[v] * (-1), v));
                }
            }
        }
    }

    // 各点への最短距離が求まったため。結果を出力する
    int sum = 0;
    for (int i = 0; i < n; i++) {
        cout << i << " " << d[i] << endl;
    }

    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 8324
final_rank: 14

code_snippet: #include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
static const int MAX = 10000;
static const int INFTY = (1 << 20);
static const int WHITE = 0;
static const int GRAY = 1;
static const int BLACK = 2;

int n;
vector<pair<int, int>> adj[MAX];

void dijkstra() {
    priority_queue<pair<int, int>> PQ;
    int color[MAX];
    int d[MAX];
    for (int i = 0; i < n; i++) {
        d[i] = INFTY;
        color[i] = WHITE;
    }
    
    d[0] = 0;
    PQ.push(make_pair(0, 0));
    color[0] = GRAY;

    while (!PQ.empty())
    {
        pair<int, int> f = PQ.top(); PQ.pop();
        int u = f.second;
        color[u] = BLACK;

        if (d[u] < f.first * (-1)) continue;

        for (int j = 0; j < adj[u].size(); j++) {
            int v = adj[u][j].first;
            if (color[v] == BLACK) continue;
            if (d[v] > d[u] + adj[u][j].second) {
                d[v] = d[u] + adj[u][j].second;
                PQ.push(make_pair(d[v] * (-1), v));
                color[v] = GRAY;
            }
        }
    }
    
    for (int i = 0; i < n; i++) {
        cout << i << " " << (d[i] == INFTY ? -1 : d[i] ) << endl;
    }
}

int main() {
    int k, u, v, c;
    
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> u >> k;
        for (int j = 0; j < k; j++) {
            cin >> v >> c;
            adj[u].push_back(make_pair(v, c));
        }
    }

    dijkstra();
    
    return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 8288
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<vector<pair<unsigned int, int>>> routes(n); // <cost, destination>
    for (int i = 0; i < n; i++)
    {
        int start, num;
        cin >> start >> num;
        for (int j = 0; j < num; j++)
        {
            unsigned int cost;
            int dest;
            cin >> dest >> cost;
            routes[start].push_back(pair<unsigned int, int>(cost, dest));
        }
    }

    vector<unsigned int> distances(n, -1); // ノードまでの距離一覧
    vector<bool> explored(n);              // 探索したノード一覧
    distances[0] = 0;
    explored[0] = true;
    int explored_num = 1;
    int currentNode = 0;
    priority_queue<pair<unsigned int, int>, vector<pair<unsigned int, int>>, greater<>> pq; // <cost, dest>

    while (explored_num != n)
    {
        for (auto [cost, dest] : routes[currentNode])
        {
            // 保存したコストより「道中のコスト+対象までのコスト」の方が小さいかつ未探索の場合は更新
            if (distances[dest] > distances[currentNode] + cost && !explored[dest])
            {
                distances[dest] = distances[currentNode] + cost;
                pq.push({distances[dest], dest});
            }
        }
        while (true)
        {
            auto [cost, dest] = pq.top();
            pq.pop();
            if (!explored[dest])
            {
                currentNode = dest;
                explored[dest] = true;
                explored_num++;
                break;
            }
        }
    }

    for (int i = 0; i < n; i++)
    {
        cout << i << " " << distances[i] << endl;
    }
}
accuracy: 1
time_ms: 110
memory_kb: 8236
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<vector<pair<unsigned int, int>>> routes(n); // <cost, destination>
    for (int i = 0; i < n; i++)
    {
        int start, num;
        cin >> start >> num;
        for (int j = 0; j < num; j++)
        {
            unsigned int cost;
            int dest;
            cin >> dest >> cost;
            routes[start].push_back(pair<unsigned int, int>(cost, dest));
        }
    }

    vector<unsigned int> destances(n, -1); // ノードまでの距離一覧
    vector<bool> explored(n);              // 探索したノード一覧
    destances[0] = 0;
    explored[0] = true;
    int explored_num = 1;
    int currentNode = 0;
    priority_queue<pair<unsigned int, int>, vector<pair<unsigned int, int>>, greater<>> pq; // <cost, dest>

    while (explored_num != n)
    {
        for (auto [cost, dest] : routes[currentNode])
        {
            // 保存したコストより「道中のコスト+対象までのコスト」の方が小さいかつ未探索の場合は更新
            if (destances[dest] > destances[currentNode] + cost && !explored[dest])
            {
                destances[dest] = destances[currentNode] + cost;
                pq.push({destances[dest], dest});
            }
        }
        while (true)
        {
            auto [cost, dest] = pq.top();
            pq.pop();
            if (!explored[dest])
            {
                currentNode = dest;
                explored[dest] = true;
                explored_num++;
                break;
            }
        }
    }

    for (int i = 0; i < n; i++)
    {
        cout << i << " " << destances[i] << endl;
    }
}
accuracy: 1
time_ms: 110
memory_kb: 8248
final_rank: 9

code_snippet: #include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<vector<pair<unsigned int, int>>> routes(n); // <cost, dist>
    for (int i = 0; i < n; i++)
    {
        int start, num;
        cin >> start >> num;
        for (int j = 0; j < num; j++)
        {
            unsigned int cost;
            int dist;
            cin >> dist >> cost;
            routes[start].push_back(pair<unsigned int, int>(cost, dist));
        }
    }

    vector<unsigned int> distances(n, -1); // ノードまでの距離一覧
    vector<bool> explored(n);              // 探索したノード一覧
    distances[0] = 0;
    explored[0] = true;
    int explored_num = 1;
    int currentNode = 0;
    priority_queue<pair<unsigned int, int>, vector<pair<unsigned int, int>>, greater<>> pq; // <cost, dist>

    while (explored_num != n)
    {
        for (auto [cost, dist] : routes[currentNode])
        {
            // 保存したコストより「道中のコスト+対象までのコスト」の方が小さいかつ未探索の場合は更新
            if (distances[dist] > distances[currentNode] + cost && !explored[dist])
            {
                distances[dist] = distances[currentNode] + cost;
                pq.push({distances[dist], dist});
            }
        }
        while (true)
        {
            auto [cost, dist] = pq.top();
            pq.pop();
            if (!explored[dist])
            {
                currentNode = dist;
                explored[dist] = true;
                explored_num++;
                break;
            }
        }
    }

    for (int i = 0; i < n; i++)
    {
        cout << i << " " << distances[i] << endl;
    }
}
accuracy: 1
time_ms: 110
memory_kb: 8236
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <queue>
using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<vector<pair<unsigned int, int>>> routes(n); // <cost, dist>
    for (int i = 0; i < n; i++)
    {
        int start, num;
        cin >> start >> num;
        for (int j = 0; j < num; j++)
        {
            unsigned int cost;
            int dist;
            cin >> dist >> cost;
            routes[start].push_back(pair<unsigned int, int>(cost, dist));
        }
    }

    vector<unsigned int> distances(n, -1); // ノードまでの距離一覧
    vector<bool> explored(n);              // 探索したノード一覧
    distances[0] = 0;
    explored[0] = true;
    int explored_num = 1;
    int currentNode = 0;
    priority_queue<pair<unsigned int, int>, vector<pair<unsigned int, int>>, greater<>> pq; // <cost, dist>

    while (explored_num != n)
    {
        for (pair<unsigned int, int> route : routes[currentNode])
        {
            unsigned int cost = route.first;
            int dist = route.second;
            // 保存したコストより「道中のコスト+対象までのコスト」の方が小さいかつ未探索の場合は更新
            if (distances[dist] > distances[currentNode] + cost && !explored[dist])
            {
                distances[dist] = distances[currentNode] + cost;
                pq.push({distances[dist], dist});
            }
        }
        while (true)
        {
            pair<int, unsigned int> p = pq.top();
            int dist = p.second;
            pq.pop();
            if (!explored[dist])
            {
                currentNode = dist;
                explored[dist] = true;
                explored_num++;
                break;
            }
        }
    }

    for (int i = 0; i < n; i++)
    {
        cout << i << " " << distances[i] << endl;
    }
}
accuracy: 1
time_ms: 110
memory_kb: 8092
final_rank: 5

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    int n;
    cin >> n;
    vector<vector<pair<unsigned int, unsigned>>> routes(n); // <dist, cost>
    for (int i = 0; i < n; i++)
    {
        int start, num;
        cin >> start >> num;
        for (int j = 0; j < num; j++)
        {
            unsigned int dist, cost;
            cin >> dist >> cost;
            routes[start].push_back(pair<unsigned int, unsigned int>(dist, cost));
        }
    }

    vector<unsigned int> distances(n, -1); // ノードまでの距離一覧
    vector<bool> explored(n);              // 探索したノード一覧
    distances[0] = 0;
    explored[0] = true;
    int explored_num = 1;
    int currentNode = 0;

    while (explored_num != n)
    {
        for (pair<unsigned int, unsigned> route : routes[currentNode])
        {
            unsigned int dist = route.first;
            unsigned int cost = route.second;
            // 保存したコストより「道中のコスト+対象までのコスト」の方が小さいかつ未探索の場合は更新
            if (distances[dist] > distances[currentNode] + cost && !explored[dist])
            {
                distances[dist] = distances[currentNode] + cost;
            }
        }
        int minNode = -1;
        unsigned int min = -1;
        for (int i = 0; i < n; i++)
        {
            // 未探索で最小のノードを取得
            if (!explored[i] && distances[i] < min)
            {
                min = distances[i];
                minNode = i;
            }
        }
        currentNode = minNode;
        explored[minNode] = true;
        explored_num++;
    }

    for (int i = 0; i < n; i++)
    {
        cout << i << " " << distances[i] << endl;
    }
}
accuracy: 1
time_ms: 280
memory_kb: 8132
final_rank: 19