Skip to content

Commit 2bdcdb0

Browse files
authored
Added task 1786.
1 parent 94d0bc4 commit 2bdcdb0

File tree

3 files changed

+182
-0
lines changed
  • src

3 files changed

+182
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package g1701_1800.s1786_number_of_restricted_paths_from_first_to_last_node;
2+
3+
// #Medium #Dynamic_Programming #Heap_Priority_Queue #Graph #Topological_Sort #Shortest_Path
4+
// #2022_04_30_Time_86_ms_(88.56%)_Space_73.5_MB_(85.34%)
5+
6+
import java.util.ArrayList;
7+
import java.util.List;
8+
import java.util.PriorityQueue;
9+
10+
@SuppressWarnings("java:S1210")
11+
public class Solution {
12+
private static class Pair implements Comparable<Pair> {
13+
int v;
14+
int cwt;
15+
16+
Pair(int v, int cwt) {
17+
this.v = v;
18+
this.cwt = cwt;
19+
}
20+
21+
public int compareTo(Pair o) {
22+
return this.cwt - o.cwt;
23+
}
24+
}
25+
26+
private static class Edge {
27+
int v;
28+
int wt;
29+
30+
Edge(int v, int wt) {
31+
this.v = v;
32+
this.wt = wt;
33+
}
34+
}
35+
36+
private int[] dtl;
37+
private int[] dp;
38+
private static final int M = 1000000007;
39+
40+
public int countRestrictedPaths(int n, int[][] edges) {
41+
List<List<Edge>> graph = buildGraph(n, edges);
42+
PriorityQueue<Pair> pq = new PriorityQueue<>();
43+
boolean[] vis = new boolean[n + 1];
44+
dtl = new int[n + 1];
45+
pq.add(new Pair(n, 0));
46+
while (!pq.isEmpty()) {
47+
Pair rem = pq.remove();
48+
if (vis[rem.v]) {
49+
continue;
50+
}
51+
dtl[rem.v] = rem.cwt;
52+
vis[rem.v] = true;
53+
for (Edge edge : graph.get(rem.v)) {
54+
if (!vis[edge.v]) {
55+
pq.add(new Pair(edge.v, rem.cwt + edge.wt));
56+
}
57+
}
58+
}
59+
dp = new int[n + 1];
60+
return dfs(graph, 1, new boolean[n + 1], n);
61+
}
62+
63+
private int dfs(List<List<Edge>> graph, int vtx, boolean[] vis, int n) {
64+
if (vtx == n) {
65+
return 1;
66+
}
67+
long ans = 0;
68+
vis[vtx] = true;
69+
for (Edge edge : graph.get(vtx)) {
70+
if (!vis[edge.v] && dtl[edge.v] < dtl[vtx]) {
71+
int x = dfs(graph, edge.v, vis, n);
72+
ans = (ans + x) % M;
73+
} else if (dtl[edge.v] < dtl[vtx] && vis[edge.v]) {
74+
ans = (ans + dp[edge.v]) % M;
75+
}
76+
}
77+
dp[vtx] = (int) ans;
78+
return (int) ans;
79+
}
80+
81+
private List<List<Edge>> buildGraph(int n, int[][] edges) {
82+
List<List<Edge>> graph = new ArrayList<>();
83+
for (int i = 0; i <= n; i++) {
84+
graph.add(new ArrayList<>());
85+
}
86+
for (int[] edge : edges) {
87+
int u = edge[0];
88+
int v = edge[1];
89+
int wt = edge[2];
90+
graph.get(u).add(new Edge(v, wt));
91+
graph.get(v).add(new Edge(u, wt));
92+
}
93+
return graph;
94+
}
95+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
1786\. Number of Restricted Paths From First to Last Node
2+
3+
Medium
4+
5+
There is an undirected weighted connected graph. You are given a positive integer `n` which denotes that the graph has `n` nodes labeled from `1` to `n`, and an array `edges` where each <code>edges[i] = [u<sub>i</sub>, v<sub>i</sub>, weight<sub>i</sub>]</code> denotes that there is an edge between nodes <code>u<sub>i</sub></code> and <code>v<sub>i</sub></code> with weight equal to <code>weight<sub>i</sub></code>.
6+
7+
A path from node `start` to node `end` is a sequence of nodes <code>[z<sub>0</sub>, z<sub>1</sub>, z<sub>2</sub>, ..., z<sub>k</sub>]</code> such that <code>z<sub>0</sub> = start</code> and <code>z<sub>k</sub> = end</code> and there is an edge between <code>z<sub>i</sub></code> and <code>z<sub>i+1</sub></code> where `0 <= i <= k-1`.
8+
9+
The distance of a path is the sum of the weights on the edges of the path. Let `distanceToLastNode(x)` denote the shortest distance of a path between node `n` and node `x`. A **restricted path** is a path that also satisfies that <code>distanceToLastNode(z<sub>i</sub>) > distanceToLastNode(z<sub>i+1</sub>)</code> where `0 <= i <= k-1`.
10+
11+
Return _the number of restricted paths from node_ `1` _to node_ `n`. Since that number may be too large, return it **modulo** <code>10<sup>9</sup> + 7</code>.
12+
13+
**Example 1:**
14+
15+
![](https://assets.leetcode.com/uploads/2021/02/17/restricted_paths_ex1.png)
16+
17+
**Input:** n = 5, edges = [[1,2,3],[1,3,3],[2,3,1],[1,4,2],[5,2,2],[3,5,1],[5,4,10]]
18+
19+
**Output:** 3
20+
21+
**Explanation:** Each circle contains the node number in black and its `distanceToLastNode value in blue.` The three restricted paths are:
22+
23+
1) 1 --> 2 --> 5
24+
25+
2) 1 --> 2 --> 3 --> 5
26+
27+
3) 1 --> 3 --> 5
28+
29+
**Example 2:**
30+
31+
![](https://assets.leetcode.com/uploads/2021/02/17/restricted_paths_ex22.png)
32+
33+
**Input:** n = 7, edges = [[1,3,1],[4,1,2],[7,3,4],[2,5,3],[5,6,1],[6,7,2],[7,5,3],[2,6,4]]
34+
35+
**Output:** 1
36+
37+
**Explanation:** Each circle contains the node number in black and its `distanceToLastNode value in blue.` The only restricted path is 1 --> 3 --> 7.
38+
39+
**Constraints:**
40+
41+
* <code>1 <= n <= 2 * 10<sup>4</sup></code>
42+
* <code>n - 1 <= edges.length <= 4 * 10<sup>4</sup></code>
43+
* `edges[i].length == 3`
44+
* <code>1 <= u<sub>i</sub>, v<sub>i</sub> <= n</code>
45+
* <code>u<sub>i</sub> != v<sub>i</sub></code>
46+
* <code>1 <= weight<sub>i</sub> <= 10<sup>5</sup></code>
47+
* There is at most one edge between any two nodes.
48+
* There is at least one path between any two nodes.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package g1701_1800.s1786_number_of_restricted_paths_from_first_to_last_node;
2+
3+
import static org.hamcrest.CoreMatchers.equalTo;
4+
import static org.hamcrest.MatcherAssert.assertThat;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
class SolutionTest {
9+
@Test
10+
void countRestrictedPaths() {
11+
assertThat(
12+
new Solution()
13+
.countRestrictedPaths(
14+
5,
15+
new int[][] {
16+
{1, 2, 3},
17+
{1, 3, 3},
18+
{2, 3, 1},
19+
{1, 4, 2},
20+
{5, 2, 2},
21+
{3, 5, 1},
22+
{5, 4, 10}
23+
}),
24+
equalTo(3));
25+
}
26+
27+
@Test
28+
void countRestrictedPaths2() {
29+
assertThat(
30+
new Solution()
31+
.countRestrictedPaths(
32+
7,
33+
new int[][] {
34+
{1, 3, 1}, {4, 1, 2}, {7, 3, 4}, {2, 5, 3}, {5, 6, 1},
35+
{6, 7, 2}, {7, 5, 3}, {2, 6, 4}
36+
}),
37+
equalTo(1));
38+
}
39+
}

0 commit comments

Comments
 (0)