O(eloge) Time Simple Dijkstra Solution || Commented Code
Code
# Code
```cpp
int helper(int node, vector<vector<pair<int, int>>> &g, vector<int> &dist, vector<int> &dp){ //simply travels from 1->n cuz dist constraint makes the graph a DAG
    if (node == g.size() - 1){ return 1; }

    if (dp[node] == -1){ //compute if not done already
        int sum = 0;
        for (int i = 0; i < g[node].size(); ++i){
            if (dist[g[node][i].first] < dist[node]){ 
                sum = (sum + helper(g[node][i].first, g, dist, dp))%1000000007;
            }
        }
        dp[node] = sum;
    }

    return dp[node];
}

int countRestrictedPaths(int n, vector<vector<int>>& edges){
    vector<vector<pair<int, int>>> g(n); //graph
    for (int i = 0; i < edges.size(); ++i){
        g[edges[i][0] - 1].push_back({edges[i][1] - 1, edges[i][2]});
        g[edges[i][1] - 1].push_back({edges[i][0] - 1, edges[i][2]});
    }

    vector<int> dist(n, INT_MAX); //stores dist b/w node i & n, using dijkstra
    dist[n - 1] = 0;
    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
    pq.push({0, n - 1});
    while (pq.size() > 0){
        int currDist = pq.top().first, node = pq.top().second;
        pq.pop();

        for (int i = 0; i < g[node].size(); ++i){
            int neighbor = g[node][i].first, toNeighbor = g[node][i].second;

            if (currDist + toNeighbor < dist[neighbor]){
                dist[neighbor] = currDist + toNeighbor;
                pq.push({dist[neighbor], neighbor});
            }
        }
    }
    
    vector<int> dp(n, -1); //1D dp 
    return helper(0, g, dist, dp);
}
```
['Dynamic Programming', 'Graph', 'Topological Sort', 'Heap (Priority Queue)', 'Shortest Path', 'C++']