Skip to content

Commit cda1f82

Browse files
Create 882. 细分图中的可到达节点.md
1 parent c398263 commit cda1f82

File tree

1 file changed

+101
-0
lines changed

1 file changed

+101
-0
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#### 882. 细分图中的可到达节点
2+
3+
难度:困难
4+
5+
---
6+
7+
给你一个无向图( **原始图** ),图中有 `n` 个节点,编号从 `0``n - 1` 。你决定将图中的每条边 **细分** 为一条节点链,每条边之间的新节点数各不相同。
8+
9+
图用由边组成的二维数组 `edges` 表示,其中 `edges[i] = [ui, vi, cnti]` 表示原始图中节点 `ui``vi` 之间存在一条边,`cnti` 是将边 **细分** 后的新节点总数。注意,`cnti == 0` 表示边不可细分。
10+
11+
**细分**`[ui, vi]` ,需要将其替换为 `(cnti + 1)` 条新边,和 `cnti` 个新节点。新节点为 `x1`, `x2`, ..., `xcnti` ,新边为 `[ui, x1]`, `[x1, x2]`, `[x2, x3]`, ..., `[xcnti+1, xcnti]`, `[xcnti, vi]`
12+
13+
现在得到一个 **新的细分图** ,请你计算从节点 `0` 出发,可以到达多少个节点?如果节点间距离是 `maxMoves` 或更少,则视为 **可以到达**
14+
15+
给你原始图和 `maxMoves` ,返回 _新的细分图中从节点 `0` 出发_ **_可到达的节点数_**
16+
17+
**示例 1:**
18+
19+
![](https://s3-lc-upload.s3.amazonaws.com/uploads/2018/08/01/origfinal.png)
20+
```
21+
输入:edges = [[0,1,10],[0,2,1],[1,2,2]], maxMoves = 6, n = 3
22+
输出:13
23+
解释:边的细分情况如上图所示。
24+
可以到达的节点已经用黄色标注出来。
25+
```
26+
27+
**示例 2:**
28+
29+
```
30+
输入:edges = [[0,1,4],[1,2,6],[0,2,8],[1,3,1]], maxMoves = 10, n = 4
31+
输出:23
32+
```
33+
34+
**示例 3:**
35+
36+
```
37+
输入:edges = [[1,2,4],[1,4,5],[1,3,1],[2,3,4],[3,4,5]], maxMoves = 17, n = 5
38+
输出:1
39+
解释:节点 0 与图的其余部分没有连通,所以只有节点 0 可以到达。
40+
```
41+
42+
**提示:**
43+
44+
* `0 <= edges.length <= min(n * (n - 1) / 2, 10^4)`
45+
* `edges[i].length == 3`
46+
* `0 <= ui < vi < n`
47+
* 图中 **不存在平行边**
48+
* `0 <= cnti <= 10^4`
49+
* `0 <= maxMoves <= 10^9`
50+
* `1 <= n <= 3000`
51+
52+
---
53+
54+
Dijkstra算法 + 堆优化:计算出最小距离后,遍历每个边的两个点,`maxMoves` 如果大于该点的最小距离,取其差值,否则为 `0` 。每个边的两点都计算一遍,如果两点的结果相加大于两点间的距离,那说明重复计算,即边上的所有节点都可以到达,加上该边的所有节点值即可,否则加上两点的结果。
55+
56+
```java
57+
class Solution {
58+
public int reachableNodes(int[][] edges, int maxMoves, int n) {
59+
int INF = Integer.MAX_VALUE, ans = 0;
60+
int[][] g = new int[n][n];
61+
for(int i = 0; i < n; i++){
62+
Arrays.fill(g[i], INF);
63+
}
64+
for(int i = 0; i < edges.length; i++){
65+
g[edges[i][0]][edges[i][1]] = edges[i][2] + 1;
66+
g[edges[i][1]][edges[i][0]] = edges[i][2] + 1;
67+
}
68+
PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[1] - b[1]); // [destination, distance]
69+
int[] distance = new int[n];
70+
Arrays.fill(distance, INF);
71+
distance[0] = 0;
72+
pq.offer(new int[]{0, 0});
73+
while(!pq.isEmpty()){
74+
int[] temp = pq.poll();
75+
int des = temp[0], dis = temp[1];
76+
if(dis > distance[des]) continue;
77+
for(int i = 0; i < n; i++){
78+
if(g[des][i] != INF){
79+
int new_dis = dis + g[des][i];
80+
if(new_dis < distance[i]){
81+
distance[i] = new_dis;
82+
pq.offer(new int[]{i, new_dis});
83+
}
84+
}
85+
}
86+
}
87+
88+
for(int i = 0; i < n; i++){
89+
if(distance[i] <= maxMoves) ans++;
90+
}
91+
for(int[] edge: edges){
92+
int u = edge[0], v = edge[1], cnt = edge[2];
93+
int a = Math.max(maxMoves - distance[u], 0);
94+
int b = Math.max(maxMoves - distance[v], 0);
95+
ans += Math.min(a + b, cnt);
96+
}
97+
return ans;
98+
}
99+
}
100+
```
101+

0 commit comments

Comments
 (0)