LeetCode/cs/second-minimum-time-to-reach-destination.cs
2024-07-28 22:57:57 +02:00

64 lines
1.9 KiB
C#

public class Solution {
private TVal Get<TKey, TVal>(Dictionary<TKey, TVal> d, TKey key, Func<TKey, TVal> constructor) {
if (!d.ContainsKey(key)) {
d[key] = constructor(key);
}
return d[key];
}
private Dictionary<int, List<int>> GetGraph(int[][] edges) {
var g = new Dictionary<int, List<int>>();
foreach (int[] edge in edges) {
var (u, v) = (edge[0], edge[1]);
Get(g, u, _ => new List<int>()).Add(v);
Get(g, v, _ => new List<int>()).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<BFSEntry>();
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;
}
}