[Tag: Easy] Textbook Dijkstra + DP
This is Dijkstra with DP, and a really good problem.MinHeap of { currCost, currDist, currNode } in priority-min of cost.
currCost : the minimum cost incurred up
This is Dijkstra with DP, and a really good problem.

MinHeap of { currCost, currDist, currNode } in priority-min of cost.
- currCost : the minimum cost incurred uptill now, in reaching currNode from sourceNode, by travelling currDist distance
- currDist: the distance (NOT MINIMUM) travelled from sourceNode till currNode wherein the cost incurred along the way is currCost
- currNode : the node we are currently at 

Cost array: cost[node][dist] = minimum cost incurred in reaching [node] from sourceNode by travelling [dist] distance.

Ans = Minimum of cost[destinationNode] over all dist
```csharp []
public class Data : IComparable<Data> {
    public int Node {get; set;}
    public int Cost {get; set;}
    public int Dist {get; set;}

    public Data(int node, int cost, int dist){
        Node = node;
        Cost = cost;
        Dist = dist;
    }

    public int CompareTo(Data other){
        int cmpCost = Cost.CompareTo(other.Cost);
        if (cmpCost != 0) return cmpCost;

        int cmpDist = Dist.CompareTo(other.Dist);
        if (cmpDist != 0) return cmpDist;

        return Node.CompareTo(other.Node);
    }
}

public class Solution {

    public int MinCost(int maxTime, int[][] edges, int[] passingFees) {

        int n = passingFees.Length;
        
        List<(int, int)>[] adj = new List<(int, int)>[n];
        for (int i = 0; i < n; i++) adj[i] = new List<(int, int)>();

        foreach (int[] edge in edges){
            int u = edge[0];
            int v = edge[1];
            int w = edge[2];
            adj[u].Add((v,w));
            adj[v].Add((u,w));
        }

        int[][] cost = new int[n][];
        for (int i = 0; i < n; i++) {
            cost[i] = Enumerable.Repeat(int.MaxValue, maxTime+1).ToArray();
        }
        
        var minHeap = new PriorityQueue<Data,Data>();

        Data startData = new Data(0,passingFees[0],0);
        cost[0][0] = startData.Cost;
        minHeap.Enqueue(startData, startData);

        while(minHeap.Count > 0){
            Data curr = minHeap.Dequeue();

            int currNode = curr.Node;
            int currDist = curr.Dist;
            int currCost = curr.Cost;

            foreach ((int,int) p in adj[currNode]){
                int adjNode = p.Item1;
                int w = p.Item2;

                int distToAdj = currDist + w;
                int costToAdj = currCost + passingFees[adjNode];

                if (distToAdj > maxTime) continue;

                // if cost decrease, then add into pq
                if (costToAdj < cost[adjNode][distToAdj]){
                    cost[adjNode][distToAdj] = costToAdj;
                    Data adjData = new Data(adjNode, costToAdj, distToAdj);
                    minHeap.Enqueue(adjData, adjData);
                }
            }
        }

        int miniCost = int.MaxValue;

        for (int i = 0; i <= maxTime; i++) miniCost = Math.Min(miniCost, cost[n-1][i]);

        return miniCost == int.MaxValue ? -1 : miniCost;

    }
}
```
['C#']