結果
問題 | No.3013 ハチマキ買い星人 |
ユーザー |
![]() |
提出日時 | 2025-01-25 13:24:53 |
言語 | C#(csc) (csc 3.9.0) |
結果 |
AC
|
実行時間 | 1,560 ms / 2,000 ms |
コード長 | 6,759 bytes |
コンパイル時間 | 4,633 ms |
コンパイル使用メモリ | 117,416 KB |
実行使用メモリ | 98,060 KB |
最終ジャッジ日時 | 2025-01-25 22:46:22 |
合計ジャッジ時間 | 39,245 ms |
ジャッジサーバーID (参考情報) |
judge4 / judge5 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 45 |
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc) Copyright (C) Microsoft Corporation. All rights reserved.
ソースコード
using System; using System.Collections.Generic; using System.Linq; class Program { static string InputPattern = "InputX"; static List<string> GetInputList() { var WillReturn = new List<string>(); if (InputPattern == "Input1") { WillReturn.Add("3 3 2 19"); WillReturn.Add("1 3 4"); WillReturn.Add("2 3 1"); WillReturn.Add("1 2 5"); WillReturn.Add("2 5"); WillReturn.Add("3 4"); //3 } else { string wkStr; while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr); } return WillReturn; } struct EdgeInfoDef { internal long ToNode; internal long Cost; } static Dictionary<long, List<EdgeInfoDef>> mEdgeInfoListDict = new Dictionary<long, List<EdgeInfoDef>>(); static Dictionary<long, long> mDEDict = new Dictionary<long, long>(); static long mY; static void Main() { List<string> InputList = GetInputList(); long[] wkArr = { }; Action<string> SplitAct = pStr => wkArr = pStr.Split(' ').Select(pX => long.Parse(pX)).ToArray(); SplitAct(InputList[0]); long N = wkArr[0]; long M = wkArr[1]; mY = wkArr[3]; foreach (string EachStr in InputList.Skip(1).Take((int)M)) { SplitAct(EachStr); long FromNode = wkArr[0]; long ToNode = wkArr[1]; long Cost = wkArr[2]; Action<long, long> AddAct = (pNode1, pNode2) => { if (mEdgeInfoListDict.ContainsKey(pNode1) == false) { mEdgeInfoListDict[pNode1] = new List<EdgeInfoDef>(); } EdgeInfoDef WillAdd; WillAdd.ToNode = pNode2; WillAdd.Cost = Cost; mEdgeInfoListDict[pNode1].Add(WillAdd); }; AddAct(FromNode, ToNode); // 正方向の辺 AddAct(ToNode, FromNode); // 逆方向の辺 } foreach (string EachStr in InputList.Skip(1 + (int)M)) { SplitAct(EachStr); long D = wkArr[0]; long E = wkArr[1]; mDEDict[D] = E; } Dijkstra(1, N); } // ダイクストラ法で、各ノードまでの最短距離を求める static void Dijkstra(long pStaNode, long pGoalNode) { var InsPQueue = new PQueue(); // 距離合計[確定ノード]なDict var KakuteiNodeDict = new Dictionary<long, long>(); KakuteiNodeDict.Add(pStaNode, 0); //Enqueue処理 Action<long> EnqueueAct = pFromNode => { if (mEdgeInfoListDict.ContainsKey(pFromNode) == false) { return; } foreach (EdgeInfoDef EachEdge in mEdgeInfoListDict[pFromNode]) { // 確定ノードならContinue if (KakuteiNodeDict.ContainsKey(EachEdge.ToNode)) continue; long wkSumCost = KakuteiNodeDict[pFromNode] + EachEdge.Cost; PQueue.PQueueJyoutaiDef WillEnqueue; WillEnqueue.Node = EachEdge.ToNode; WillEnqueue.SumCost = wkSumCost; InsPQueue.Enqueue(WillEnqueue); } }; EnqueueAct(pStaNode); while (InsPQueue.IsEmpty() == false) { PQueue.PQueueJyoutaiDef Dequeued = InsPQueue.Dequeue(); // 確定ノードならcontinue if (KakuteiNodeDict.ContainsKey(Dequeued.Node)) continue; // 枝切り // if (KakuteiNodeDict.ContainsKey(pGoalNode)) break; KakuteiNodeDict.Add(Dequeued.Node, Dequeued.SumCost); EnqueueAct(Dequeued.Node); } var AnswerList = new List<long>(); for (int I = 1; I <= pGoalNode; I++) { if (KakuteiNodeDict.ContainsKey(I)) { //Console.WriteLine(KakuteiNodeDict[I]); if (mDEDict.ContainsKey(I)) { long Rest = mY - KakuteiNodeDict[I]; if (Rest > 0) { AnswerList.Add(Rest/mDEDict[I]); } } } else { //Console.WriteLine(-1); } } if (AnswerList.Count == 0) { Console.WriteLine(0); } else { Console.WriteLine(AnswerList.Max()); } } } #region PQueue // 優先度付きキュー internal class PQueue { internal struct PQueueJyoutaiDef { internal long Node; internal long SumCost; } private Dictionary<long, PQueueJyoutaiDef> mHeapDict = new Dictionary<long, PQueueJyoutaiDef>(); internal bool IsEmpty() { return mHeapDict.Count == 0; } // エンキュー処理 internal void Enqueue(PQueueJyoutaiDef pAddJyoutai) { long CurrNode = 1 + mHeapDict.Count; mHeapDict[CurrNode] = pAddJyoutai; while (1 < CurrNode && mHeapDict[CurrNode / 2].SumCost > mHeapDict[CurrNode].SumCost) { PQueueJyoutaiDef Swap = mHeapDict[CurrNode]; mHeapDict[CurrNode] = mHeapDict[CurrNode / 2]; mHeapDict[CurrNode / 2] = Swap; CurrNode /= 2; } } // デキュー処理 internal PQueueJyoutaiDef Dequeue() { PQueueJyoutaiDef TopNode = mHeapDict[1]; long LastNode = mHeapDict.Count; mHeapDict[1] = mHeapDict[LastNode]; mHeapDict.Remove(LastNode); MinHeapify(1); return TopNode; } // 根ノードを指定し、根から葉へヒープ構築 private void MinHeapify(long pRootNode) { if (mHeapDict.Count <= 1) { return; } long Left = pRootNode * 2; long Right = pRootNode * 2 + 1; // 左の子、自分、右の子で値が最小のノードを選ぶ long Smallest = mHeapDict[pRootNode].SumCost; long SmallestNode = pRootNode; if (mHeapDict.ContainsKey(Left) && mHeapDict[Left].SumCost < Smallest) { Smallest = mHeapDict[Left].SumCost; SmallestNode = Left; } if (mHeapDict.ContainsKey(Right) && mHeapDict[Right].SumCost < Smallest) { Smallest = mHeapDict[Right].SumCost; SmallestNode = Right; } // 子ノードのほうが大きい場合 if (SmallestNode != pRootNode) { PQueueJyoutaiDef Swap = mHeapDict[SmallestNode]; mHeapDict[SmallestNode] = mHeapDict[pRootNode]; mHeapDict[pRootNode] = Swap; // 再帰的に呼び出し MinHeapify(SmallestNode); } } } #endregion