using System; using System.IO; using System.Linq; using System.Collections; using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using System.Text.RegularExpressions; using static System.Math; using Debug = System.Diagnostics.Debug; using MethodImplOptions = System.Runtime.CompilerServices.MethodImplOptions; using MethodImplAttribute = System.Runtime.CompilerServices.MethodImplAttribute; static class P { static void Main() { //頂点それぞれについてツアー //1→i→1 //単一始点最短路を打って //1減る ということを var nm = Console.ReadLine().Split().Select(int.Parse).ToList(); List>[] neighbour = Enumerable.Repeat(0, nm[0]).Select(_ => new List>()).ToArray(); for (int i = 0; i < nm[1]; i++) { var abc = Console.ReadLine().Split().Select(int.Parse).ToList(); neighbour[abc[0] - 1].Add(new Tuple(abc[1] - 1, abc[2])); neighbour[abc[1] - 1].Add(new Tuple(abc[0] - 1, abc[2])); } //0-(n-1) : 通常の点 //n-(2*n-1) : 既にvipチケ使った点 int[] distances = Enumerable.Repeat(-1, nm[0] * 2).ToArray(); PriorityQueue> pqueue = new PriorityQueue>(nm[1], (x, y) => x.Item1 < y.Item1); pqueue.Push(new Tuple(0, 0)); while (pqueue.Count > 0) { var item = pqueue.Pop(); //Debug.WriteLine($"{item.Item2} {item.Item1}"); if (distances[item.Item2] >= 0) continue; distances[item.Item2] = item.Item1; if (item.Item2 >= nm[0]) { foreach (var edge in neighbour[item.Item2 - nm[0]]) { pqueue.Push(new Tuple(item.Item1 + edge.Item2, edge.Item1 + nm[0])); } } else { foreach (var edge in neighbour[item.Item2]) { pqueue.Push(new Tuple(item.Item1 + edge.Item2, edge.Item1)); pqueue.Push(new Tuple(item.Item1, edge.Item1 + nm[0])); } } } Console.WriteLine(string.Join("\n", distances.Zip(distances.Skip(nm[0]), (x, y) => x + Min(x, y)))); } } // Microsoft Windows Client Platform // Copyright (C) Microsoft Corporation. All rights reserved. internal class PriorityQueue where T : IComparable { private T[] _heap; private const int DefaultCapacity = 6; Func Larger; public PriorityQueue(int capacity, Func larger) { Count = 0; _heap = new T[capacity > 0 ? capacity : DefaultCapacity]; Larger = larger; } public int Count { get; set; } public T Top { get { Debug.Assert(Count > 0); return _heap[0]; } } public void Push(T value) { if (Count == _heap.Length) { T[] temp = new T[Count * 2]; for (int i = 0; i < Count; ++i) { temp[i] = _heap[i]; } _heap = temp; } int index = Count; while (index > 0) { int parentIndex = (index - 1) / 2; if (!Larger(value, _heap[parentIndex])) break; _heap[index] = _heap[parentIndex]; index = parentIndex; } _heap[index] = value; Count++; } public T Pop() { T top = Top; Debug.Assert(Count != 0); if (Count > 1) { int parent = 0; int leftChild = (parent * 2) + 1; while (leftChild < Count) { int rightChild = leftChild + 1; int bestChild = (rightChild < Count && Larger(_heap[rightChild], _heap[leftChild])) ? rightChild : leftChild; _heap[parent] = _heap[bestChild]; parent = bestChild; leftChild = (parent * 2) + 1; } _heap[parent] = _heap[Count - 1]; } Count--; return top; } }