Skip to content

Commit ab7e4b7

Browse files
committed
feat: add solutions to lc problem: No.0882
No.0882.Reachable Nodes In Subdivided Graph
1 parent 262b09f commit ab7e4b7

File tree

6 files changed

+516
-2
lines changed

6 files changed

+516
-2
lines changed

solution/0800-0899/0882.Reachable Nodes In Subdivided Graph/README.md

Lines changed: 191 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,212 @@
6060

6161
<!-- 这里可写通用的实现逻辑 -->
6262

63+
**方法一:Dijkstra 算法**
64+
65+
这道题本质是求从节点 $0$ 出发,最多经过 $maxMoves$ 步,可以到达多少个节点。单源最短路,且边权非负,我们可以考虑使用 Dijkstra 算法。
66+
67+
根据题目描述,节点 $u_i$ 到节点 $v_i$ 之间存在 $cnt_i$ 个新节点,那么节点 $u_i$ 到节点 $v_i$ 的距离为 $cnt_i + 1$。
68+
69+
我们举个简单的例子,以下节点 $1$ 和节点 $2$ 之间存在 $3$ 个新节点,那么节点 $1$ 到节点 $2$ 之间有 $4$ 条边,也即距离为 $4$。
70+
71+
```
72+
1 -- o -- o -- o -- 2
73+
```
74+
75+
因此,我们可以将原图中两点之间新节点的个数 $cnt_i$ 加 $1$,得到两点之间的距离。然后构建一个邻接表 $g$,用于存储每个节点的邻接节点以及到达邻接节点的距离。
76+
77+
接下来,我们使用 Dijkstra 算法求出从节点 $0$ 到原始图其余所有节点的最短距离,存储在数组 $dist$ 中。
78+
79+
然后,我们遍历数组 $dist$,统计其中小于等于 $maxMoves$ 的节点个数,也就是我们可以到达的节点数。不过,这并不是最终答案,我们还需要加上新节点中符合条件的节点个数。
80+
81+
我们可以发现,如果我们能在 $dist[u]$ 步到达节点 $u$(其中 $dist[u] \leq maxMoves$),并且节点 $u$ 到节点 $v$ 之间有 $cnt$ 个新节点,那么我们能通过节点 $u$ 到达的新节点个数 $a=\min(cnt, maxMoves - dist[u])$。同理,我们能通过节点 $v$ 到达的新节点个数 $b=\min(cnt, maxMoves - dist[v])$。那么,我们能到达节点 $u$ 和节点 $v$ 之间的新节点个数为 $\min(cnt, a + b)$。
82+
83+
因此,我们再遍历所有的边,统计其中能到达的新节点个数,累加到答案中即可。
84+
85+
时间复杂度 $O(m \times \log n)$,其中 $m$ 和 $n$ 分别为边数和节点数。
86+
6387
<!-- tabs:start -->
6488

6589
### **Python3**
6690

6791
<!-- 这里可写当前语言的特殊实现逻辑 -->
6892

6993
```python
70-
94+
class Solution:
95+
def reachableNodes(self, edges: List[List[int]], maxMoves: int, n: int) -> int:
96+
g = defaultdict(list)
97+
for u, v, cnt in edges:
98+
g[u].append((v, cnt + 1))
99+
g[v].append((u, cnt + 1))
100+
q = [(0, 0)]
101+
dist = [0] + [inf] * n
102+
while q:
103+
d, u = heappop(q)
104+
for v, cnt in g[u]:
105+
if (t := d + cnt) < dist[v]:
106+
dist[v] = t
107+
q.append((t, v))
108+
ans = sum(d <= maxMoves for d in dist)
109+
for u, v, cnt in edges:
110+
a = min(cnt, max(0, maxMoves - dist[u]))
111+
b = min(cnt, max(0, maxMoves - dist[v]))
112+
ans += min(cnt, a + b)
113+
return ans
71114
```
72115

73116
### **Java**
74117

75118
<!-- 这里可写当前语言的特殊实现逻辑 -->
76119

77120
```java
121+
class Solution {
122+
public int reachableNodes(int[][] edges, int maxMoves, int n) {
123+
List<int[]>[] g = new List[n];
124+
for (int i = 0; i < n; ++i) {
125+
g[i] = new ArrayList<>();
126+
}
127+
for (var e : edges) {
128+
int u = e[0], v = e[1], cnt = e[2] + 1;
129+
g[u].add(new int[] {v, cnt});
130+
g[v].add(new int[] {u, cnt});
131+
}
132+
int[] dist = new int[n];
133+
Arrays.fill(dist, 1 << 30);
134+
PriorityQueue<int[]> q = new PriorityQueue<>((a, b) -> a[0] - b[0]);
135+
q.offer(new int[] {0, 0});
136+
dist[0] = 0;
137+
while (!q.isEmpty()) {
138+
var p = q.poll();
139+
int d = p[0], u = p[1];
140+
for (var nxt : g[u]) {
141+
int v = nxt[0], cnt = nxt[1];
142+
if (d + cnt < dist[v]) {
143+
dist[v] = d + cnt;
144+
q.offer(new int[] {dist[v], v});
145+
}
146+
}
147+
}
148+
int ans = 0;
149+
for (int d : dist) {
150+
if (d <= maxMoves) {
151+
++ans;
152+
}
153+
}
154+
for (var e : edges) {
155+
int u = e[0], v = e[1], cnt = e[2];
156+
int a = Math.min(cnt, Math.max(0, maxMoves - dist[u]));
157+
int b = Math.min(cnt, Math.max(0, maxMoves - dist[v]));
158+
ans += Math.min(cnt, a + b);
159+
}
160+
return ans;
161+
}
162+
}
163+
```
164+
165+
### **C++**
166+
167+
```cpp
168+
class Solution {
169+
public:
170+
int reachableNodes(vector<vector<int>>& edges, int maxMoves, int n) {
171+
using pii = pair<int, int>;
172+
vector<vector<pii>> g(n);
173+
for (auto& e : edges) {
174+
int u = e[0], v = e[1], cnt = e[2] + 1;
175+
g[u].emplace_back(v, cnt);
176+
g[v].emplace_back(u, cnt);
177+
}
178+
priority_queue<pii, vector<pii>, greater<pii>> q;
179+
q.emplace(0, 0);
180+
int dist[n];
181+
memset(dist, 0x3f, sizeof dist);
182+
dist[0] = 0;
183+
while (!q.empty()) {
184+
auto [d, u] = q.top();
185+
q.pop();
186+
for (auto& [v, cnt] : g[u]) {
187+
if (d + cnt < dist[v]) {
188+
dist[v] = d + cnt;
189+
q.emplace(dist[v], v);
190+
}
191+
}
192+
}
193+
int ans = 0;
194+
for (int& d : dist) ans += d <= maxMoves;
195+
for (auto& e : edges) {
196+
int u = e[0], v = e[1], cnt = e[2];
197+
int a = min(cnt, max(0, maxMoves - dist[u]));
198+
int b = min(cnt, max(0, maxMoves - dist[v]));
199+
ans += min(cnt, a + b);
200+
}
201+
return ans;
202+
}
203+
};
204+
```
78205
206+
### **Go**
207+
208+
```go
209+
func reachableNodes(edges [][]int, maxMoves int, n int) (ans int) {
210+
g := make([][]pair, n)
211+
for _, e := range edges {
212+
u, v, cnt := e[0], e[1], e[2]+1
213+
g[u] = append(g[u], pair{cnt, v})
214+
g[v] = append(g[v], pair{cnt, u})
215+
}
216+
dist := make([]int, n)
217+
for i := range dist {
218+
dist[i] = 1 << 30
219+
}
220+
dist[0] = 0
221+
q := hp{{0, 0}}
222+
for len(q) > 0 {
223+
p := heap.Pop(&q).(pair)
224+
d, u := p.v, p.i
225+
for _, nxt := range g[u] {
226+
v, cnt := nxt.i, nxt.v
227+
if d+cnt < dist[v] {
228+
dist[v] = d + cnt
229+
heap.Push(&q, pair{dist[v], v})
230+
}
231+
}
232+
}
233+
for _, d := range dist {
234+
if d <= maxMoves {
235+
ans++
236+
}
237+
}
238+
for _, e := range edges {
239+
u, v, cnt := e[0], e[1], e[2]
240+
a := min(cnt, max(0, maxMoves-dist[u]))
241+
b := min(cnt, max(0, maxMoves-dist[v]))
242+
ans += min(cnt, a+b)
243+
}
244+
return
245+
}
246+
247+
type pair struct{ v, i int }
248+
type hp []pair
249+
250+
func (h hp) Len() int { return len(h) }
251+
func (h hp) Less(i, j int) bool { return h[i].v < h[j].v }
252+
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
253+
func (h *hp) Push(v interface{}) { *h = append(*h, v.(pair)) }
254+
func (h *hp) Pop() interface{} { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
255+
256+
func max(a, b int) int {
257+
if a > b {
258+
return a
259+
}
260+
return b
261+
}
262+
263+
func min(a, b int) int {
264+
if a < b {
265+
return a
266+
}
267+
return b
268+
}
79269
```
80270

81271
### **...**

solution/0800-0899/0882.Reachable Nodes In Subdivided Graph/README_EN.md

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,179 @@ The nodes that are reachable are highlighted in yellow.
5959
### **Python3**
6060

6161
```python
62-
62+
class Solution:
63+
def reachableNodes(self, edges: List[List[int]], maxMoves: int, n: int) -> int:
64+
g = defaultdict(list)
65+
for u, v, cnt in edges:
66+
g[u].append((v, cnt + 1))
67+
g[v].append((u, cnt + 1))
68+
q = [(0, 0)]
69+
dist = [0] + [inf] * n
70+
while q:
71+
d, u = heappop(q)
72+
for v, cnt in g[u]:
73+
if (t := d + cnt) < dist[v]:
74+
dist[v] = t
75+
q.append((t, v))
76+
ans = sum(d <= maxMoves for d in dist)
77+
for u, v, cnt in edges:
78+
a = min(cnt, max(0, maxMoves - dist[u]))
79+
b = min(cnt, max(0, maxMoves - dist[v]))
80+
ans += min(cnt, a + b)
81+
return ans
6382
```
6483

6584
### **Java**
6685

6786
```java
87+
class Solution {
88+
public int reachableNodes(int[][] edges, int maxMoves, int n) {
89+
List<int[]>[] g = new List[n];
90+
for (int i = 0; i < n; ++i) {
91+
g[i] = new ArrayList<>();
92+
}
93+
for (var e : edges) {
94+
int u = e[0], v = e[1], cnt = e[2] + 1;
95+
g[u].add(new int[] {v, cnt});
96+
g[v].add(new int[] {u, cnt});
97+
}
98+
int[] dist = new int[n];
99+
Arrays.fill(dist, 1 << 30);
100+
PriorityQueue<int[]> q = new PriorityQueue<>((a, b) -> a[0] - b[0]);
101+
q.offer(new int[] {0, 0});
102+
dist[0] = 0;
103+
while (!q.isEmpty()) {
104+
var p = q.poll();
105+
int d = p[0], u = p[1];
106+
for (var nxt : g[u]) {
107+
int v = nxt[0], cnt = nxt[1];
108+
if (d + cnt < dist[v]) {
109+
dist[v] = d + cnt;
110+
q.offer(new int[] {dist[v], v});
111+
}
112+
}
113+
}
114+
int ans = 0;
115+
for (int d : dist) {
116+
if (d <= maxMoves) {
117+
++ans;
118+
}
119+
}
120+
for (var e : edges) {
121+
int u = e[0], v = e[1], cnt = e[2];
122+
int a = Math.min(cnt, Math.max(0, maxMoves - dist[u]));
123+
int b = Math.min(cnt, Math.max(0, maxMoves - dist[v]));
124+
ans += Math.min(cnt, a + b);
125+
}
126+
return ans;
127+
}
128+
}
129+
```
130+
131+
### **C++**
132+
133+
```cpp
134+
class Solution {
135+
public:
136+
int reachableNodes(vector<vector<int>>& edges, int maxMoves, int n) {
137+
using pii = pair<int, int>;
138+
vector<vector<pii>> g(n);
139+
for (auto& e : edges) {
140+
int u = e[0], v = e[1], cnt = e[2] + 1;
141+
g[u].emplace_back(v, cnt);
142+
g[v].emplace_back(u, cnt);
143+
}
144+
priority_queue<pii, vector<pii>, greater<pii>> q;
145+
q.emplace(0, 0);
146+
int dist[n];
147+
memset(dist, 0x3f, sizeof dist);
148+
dist[0] = 0;
149+
while (!q.empty()) {
150+
auto [d, u] = q.top();
151+
q.pop();
152+
for (auto& [v, cnt] : g[u]) {
153+
if (d + cnt < dist[v]) {
154+
dist[v] = d + cnt;
155+
q.emplace(dist[v], v);
156+
}
157+
}
158+
}
159+
int ans = 0;
160+
for (int& d : dist) ans += d <= maxMoves;
161+
for (auto& e : edges) {
162+
int u = e[0], v = e[1], cnt = e[2];
163+
int a = min(cnt, max(0, maxMoves - dist[u]));
164+
int b = min(cnt, max(0, maxMoves - dist[v]));
165+
ans += min(cnt, a + b);
166+
}
167+
return ans;
168+
}
169+
};
170+
```
68171
172+
### **Go**
173+
174+
```go
175+
func reachableNodes(edges [][]int, maxMoves int, n int) (ans int) {
176+
g := make([][]pair, n)
177+
for _, e := range edges {
178+
u, v, cnt := e[0], e[1], e[2]+1
179+
g[u] = append(g[u], pair{cnt, v})
180+
g[v] = append(g[v], pair{cnt, u})
181+
}
182+
dist := make([]int, n)
183+
for i := range dist {
184+
dist[i] = 1 << 30
185+
}
186+
dist[0] = 0
187+
q := hp{{0, 0}}
188+
for len(q) > 0 {
189+
p := heap.Pop(&q).(pair)
190+
d, u := p.v, p.i
191+
for _, nxt := range g[u] {
192+
v, cnt := nxt.i, nxt.v
193+
if d+cnt < dist[v] {
194+
dist[v] = d + cnt
195+
heap.Push(&q, pair{dist[v], v})
196+
}
197+
}
198+
}
199+
for _, d := range dist {
200+
if d <= maxMoves {
201+
ans++
202+
}
203+
}
204+
for _, e := range edges {
205+
u, v, cnt := e[0], e[1], e[2]
206+
a := min(cnt, max(0, maxMoves-dist[u]))
207+
b := min(cnt, max(0, maxMoves-dist[v]))
208+
ans += min(cnt, a+b)
209+
}
210+
return
211+
}
212+
213+
type pair struct{ v, i int }
214+
type hp []pair
215+
216+
func (h hp) Len() int { return len(h) }
217+
func (h hp) Less(i, j int) bool { return h[i].v < h[j].v }
218+
func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
219+
func (h *hp) Push(v interface{}) { *h = append(*h, v.(pair)) }
220+
func (h *hp) Pop() interface{} { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
221+
222+
func max(a, b int) int {
223+
if a > b {
224+
return a
225+
}
226+
return b
227+
}
228+
229+
func min(a, b int) int {
230+
if a < b {
231+
return a
232+
}
233+
return b
234+
}
69235
```
70236

71237
### **...**

0 commit comments

Comments
 (0)