//dijkstra算法 求单源最短路径(板子) O(n^2)还能优化,等会补充
#include<iostream>//important (不能求带负权值的图)
#include<cstdio>
#include<cstring>
#define inf (0x3f3f3f3f)
using namespace std;
const int maxn = 100 + 15;
int Grape[maxn][maxn];//u - v的路径的权
int n;
bool vis[maxn];//判断节点是否访问过
int d[maxn];
void dijkstra()
{
memset(d,inf,sizeof(d));
memset(vis,false,sizeof(vis));
d[0] = 0;//d里存储着各个顶点到源点的距离
while(true)
{
int mincost = inf;
int u = 0;
for(int v=0;v!=n;++v)
{
if(!vis[v]&&d[v]<mincost)
{
mincost = d[v];
u = v;
}
}
if(mincost == inf)
break;
vis[u] = true;
//通过u更新
for(int v=0;v!=n;++v)
{
if(!vis[v]&&Grape[u][v]!=0)//u - v存在边 且v节点未被访问
{
if(d[u]+Grape[u][v]<d[v])
{
d[v] = d[u] + Grape[u][v];
}
}
}
}
for(int i=0;i!=n;++i)
cout<<i<<" "<<d[i]<<endl;
}
int main()
{
cin>>n;
int tmp = n;
int u,num,v,value;
while(tmp--)
{
cin>>u>>num;
while(num--)
{
cin>>v>>value;
Grape[u][v] = value;//if 0表示u - v节点之间不存在权值边
}
}//构建图
// for(int i=0;i!=n;++i)
// {
// for(int j=0;j!=n;++j)
// cout<<Grape[i][j];
// cout<<endl;
// }
dijkstra();
}
知识兔