diff --git a/cs/second-minimum-time-to-reach-destination.cs b/cs/second-minimum-time-to-reach-destination.cs new file mode 100644 index 0000000..191b0ee --- /dev/null +++ b/cs/second-minimum-time-to-reach-destination.cs @@ -0,0 +1,64 @@ +public class Solution { + private TVal Get(Dictionary d, TKey key, Func constructor) { + if (!d.ContainsKey(key)) { + d[key] = constructor(key); + } + return d[key]; + } + + private Dictionary> GetGraph(int[][] edges) { + var g = new Dictionary>(); + + foreach (int[] edge in edges) { + var (u, v) = (edge[0], edge[1]); + Get(g, u, _ => new List()).Add(v); + Get(g, v, _ => new List()).Add(u); + } + + return g; + } + + private record BFSEntry(int Node, int Index); + + public int SecondMinimum(int n, int[][] edges, int time, int change) { + var graph = GetGraph(edges); + + var distances = new int[n + 1, 2]; + for (var i = 1; i <= n; ++i) { + distances[i, 0] = distances[i, 1] = -1; + } + + var q = new Queue(); + q.Enqueue(new BFSEntry(1, 0)); + distances[1, 0] = 0; + + while (q.TryDequeue(out var entry)) { + var spentTime = distances[entry.Node, entry.Index]; + if ((spentTime / change) % 2 == 1) { + spentTime = time + change * (spentTime / change + 1); + } else { + spentTime += time; + } + + if (!graph.ContainsKey(entry.Node)) { + continue; + } + + foreach (var node in graph[entry.Node]) { + if (distances[node, 0] == -1) { + distances[node, 0] = spentTime; + q.Enqueue(new BFSEntry(node, 0)); + } else if (distances[node, 1] == -1 && distances[node, 0] != spentTime) { + if (node == n) { + return spentTime; + } + + distances[node, 1] = spentTime; + q.Enqueue(new BFSEntry(node, 1)); + } + } + } + + return 0; + } +}