#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<utility>

#define INF 9999999999

using namespace std;

const int MAX_N = 100000;

int d[MAX_N];

struct edge{
	int to;   //?????????
	int cost; //?????????
};

typedef pair<int,int>P;

void dijkstra(int s,int n)
{
	int k,l,p,q,r,u,v,cost,m;
	vector<edge> edgelist[n];
	for(int i=0;i<n;i++){
		scanf("%d",&u);
		scanf("%d",&m);
		for(int j=0;j<m;j++){
			edge e;
			scanf("%d",&v);
			scanf("%d",&cost);
			e.to = v;	e.cost = cost;
			edgelist[i].push_back(e);
		}
	}
	priority_queue<P,vector<P>,greater<P> > que;
	d[s] = 0;
	que.push(P(0,s));
	while(!que.empty()){
		P p = que.top();
		que.pop();
		int v = p.second;
		if(d[v] < p.first) continue;
		vector<edge>::iterator it = edgelist[v].begin();
		while(it != edgelist[v].end()){
			if(d[it->to] > d[v] + it->cost){
				d[it->to] = d[v] + it->cost;
				que.push(P(d[it->to],it->to));
			}
			it++;
		}
	}
}

int main()
{
	int k,l,m,n,s;
	scanf("%d",&n); // ?????°?????\???
	fill(d,d+n,INF);
	dijkstra(0,n);
	for(int i=0;i<n;i++){
		printf("%d %d\n",i,d[i]);
	}
}