/* import heapq n,m,k = map(int,input().split()) graph = {} for i in range(1,n+1): graph[i] = [] edgs = [] for i in range(m): a,b,c = map(int,input().split()) edgs.append((a,b,c)) graph[a].append((b,c+k)) graph[b].append((a,c+k)) kakutei = [False]*(n+1) heap = [(0,1)] cur = [float('inf')]*(n+1) cur[1] = 0 while heap: n_dis,node = heapq.heappop(heap) if kakutei[node]: continue kakutei[node] = True for nei,n_dis in graph[node]: if cur[node]+n_dis < cur[nei]: heapq.heappush(heap,(cur[node]+n_dis,nei)) cur[nei] = cur[node]+n_dis mae_cur = cur[:] for i in range(n+1,2*n+1): graph[i] = [] for a,b,c in edgs: graph[a].append((b+n,k)) graph[b].append((a+n,k)) graph[a+n].append((b+n,c+k)) graph[b+n].append((a+n,c+k)) n *= 2 kakutei = [False]*(n+1) heap = [(0,n//2)] cur = [float('inf')]*(n+1) cur[n//2] = 0 while heap: n_dis,node = heapq.heappop(heap) if kakutei[node]: continue kakutei[node] = True for nei,n_dis in graph[node]: if cur[node]+n_dis < cur[nei]: heapq.heappush(heap,(cur[node]+n_dis,nei)) cur[nei] = cur[node]+n_dis n = n//2 for i in range(2,n+1): print(min(mae_cur[i]+cur[i+n],mae_cur[-1])) */ #include using namespace std; // Direct translation from the Python code above. // Algorithm / time complexity unchanged. using ll = long long; const ll INF = (LLONG_MAX / 4); int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n0, m; ll k; if (!(cin >> n0 >> m >> k)) return 0; // We'll allocate space for 2 * n0 nodes (1-indexed) int total_nodes = 2 * n0; vector>> graph(total_nodes + 1); vector> edgs; for (int i = 0; i < m; ++i) { int a, b; ll c; cin >> a >> b >> c; edgs.emplace_back(a, b, c); ll w = c + k; graph[a].push_back({b, w}); graph[b].push_back({a, w}); } // First Dijkstra on original graph (nodes 1..n0) vector kakutei(n0 + 1, false); vector cur(n0 + 1, INF); cur[1] = 0; priority_queue, vector>, greater>> pq; pq.push({0LL, 1}); while (!pq.empty()) { auto [d, node] = pq.top(); pq.pop(); if (node < 1 || node > n0) continue; // safety, mimic original's domain if (kakutei[node]) continue; kakutei[node] = true; for (auto &e : graph[node]) { int nei = e.first; ll w = e.second; if (cur[node] + w < cur[nei]) { cur[nei] = cur[node] + w; pq.push({cur[nei], nei}); } } } vector mae_cur = cur; // copy // Ensure nodes n0+1 .. 2*n0 exist (graph already sized) // Add edges according to the Python code for (auto &t : edgs) { int a, b; ll c; tie(a, b, c) = t; // graph[a].append((b+n,k)) graph[a].push_back({b + n0, k}); graph[b].push_back({a + n0, k}); graph[a + n0].push_back({b + n0, c + k}); graph[b + n0].push_back({a + n0, c + k}); } // Second Dijkstra on expanded graph (nodes 1..2*n0), start at n0 int n = 2 * n0; vector kakutei2(n + 1, false); vector cur2(n + 1, INF); int start = n0; // n//2 in python after doubling cur2[start] = 0; priority_queue, vector>, greater>> pq2; pq2.push({0LL, start}); while (!pq2.empty()) { auto [d, node] = pq2.top(); pq2.pop(); if (kakutei2[node]) continue; kakutei2[node] = true; for (auto &e : graph[node]) { int nei = e.first; ll w = e.second; if (cur2[node] + w < cur2[nei]) { cur2[nei] = cur2[node] + w; pq2.push({cur2[nei], nei}); } } } // Print results: for i in range(2, n0+1): print(min(mae_cur[i]+cur[i+n0], mae_cur[-1])) // mae_cur[-1] in Python is mae_cur[n0] ll mae_last = mae_cur[n0]; // Collect outputs and print (one per line) for (int i = 2; i <= n0; ++i) { ll a = mae_cur[i]; ll b = INF; if (i + n0 <= n) b = cur2[i + n0]; ll ans = min( (a==INF || b==INF) ? INF : (a + b), mae_last ); if (ans >= INF/2) { // Python would print large float('inf') but in contest it's typical to print something; // To stay faithful to the algorithmic translation, we'll print a large number representation. // This is a straightforward translation choice (no algorithmic change). cout << (long long)INF << '\n'; } else { cout << ans << '\n'; } } return 0; }