#include <bits/stdc++.h>
using namespace std;
typedef int H[50005];
const int inf = 0x3f3f3f3f;
int n, m;
int dist[50005];
bitset <50005> viz;
H Heap;
vector < pair <int, int> > graf[50005];
inline int father(int x)
{
return x >> 1;
}
inline int left_son(int x)
{
return x << 1;
}
inline int right_son(int x)
{
return (x << 1) + 1;
}
void downHeap(H Heap, int n, int k)
{
int son = 1;
for (; son;)
{
son = 0;
if (left_son(k) <= n)
{
son = left_son(k);
if (right_son(k) <= n && dist[ Heap[left_son(k)]] > dist[ Heap[right_son(k)]])
son = right_son(k);
}
if (dist[ Heap[son]] > dist[ Heap[k]])
son = 0;
if (son)
swap(Heap[k], Heap[son]);
k = son;
}
}
void upHeap(H Heap, int n, int k)
{
for (; k > 1;)
{
if (dist[ Heap[father(k)]] > dist[ Heap[k]])
swap(Heap[k], Heap[father(k)]);
else return;
k = father(k);
}
}
void insert(H Heap, int &n, int x)
{
n++;
Heap[n] = x;
upHeap(Heap, n, n);
}
void remove(H Heap, int &n, int k)
{
swap(Heap[k], Heap[n]);
Heap[n] = 0;
n--;
if (k > 1 && (dist[ Heap[k]] < dist[ Heap[father(k)]]))
upHeap(Heap, n, k);
else downHeap(Heap, n, k);
}
void dijkstra()
{
memset(dist, inf, sizeof dist);
memset(Heap, 0, sizeof Heap);
Heap[0] = Heap[1] = 1;
dist[1] = 0;
viz.reset();
while (Heap[0])
{
int nod = Heap[1];
remove(Heap, Heap[0], 1);
for (vector < pair <int, int> >::iterator it = graf[nod].begin(); it != graf[nod].end(); it++)
if (!viz[it->first])
{
int next_nod = it->first, next_dist = it->second;
if (dist[next_nod] > dist[nod] + next_dist)
{
dist[next_nod] = dist[nod] + next_dist;
insert(Heap, Heap[0], next_nod);
viz[next_nod] = true;
}
}
}
}
int main()
{
freopen("dijkstra.in", "r", stdin);
freopen("dijkstra.out", "w", stdout);
scanf("%d %d", &n, &m);
for (int i = 1, a, b, c; i <= m; i++)
scanf("%d %d %d", &a, &b, &c),
graf[a].push_back(make_pair(b, c));
dijkstra();
for (int i = 2; i <= n; i++)
printf("%d ", dist[i] == inf ? 0 : dist[i]);
return 0;
}
///min-Heap
/**
function Dijkstra(Graph, source):
dist[source] = 0 // Initialization
create vertex set Q
for each vertex v in Graph:
if v != source
dist[v] = INFINITY // Unknown distance from source to v
Q.add_with_priority(v, dist[v])
while Q is not empty: // The main loop
u = Q.extract_min() // Remove and return best vertex
for each neighbor v of u: // only v that is still in Q
alt = dist[u] + length(u, v)
if alt < dist[v]
dist[v] = alt
Q.decrease_priority(v, alt)
return dist[]
*/