Skip to content

Commit 5ef7a8f

Browse files
authored
Merge pull request apachecn#54 from yudaer/master
Create 882._Reachable_Nodes_In_Subdivided_Graph.md
2 parents 6e5411c + 888cd5d commit 5ef7a8f

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
### 899. Reachable Nodes In Subdivided Graph
2+
3+
4+
5+
题目:
6+
https://leetcode.com/problems/reachable-nodes-in-subdivided-graph/
7+
8+
难度:
9+
Hard
10+
11+
题意:
12+
13+
1. 给定一张图,图上有无向边,边上有等距的点
14+
2. 从0出发,最长路径能够访问M个点,问总共能访问多少个点
15+
16+
思路:
17+
18+
- 这个题是最短路的变种
19+
- 边上面点的个数就是边的权值,先做一遍最短路
20+
- 扫描每个边,判断左右两个端点的值,进行累加
21+
- 左/右 端点大于M的,不累加
22+
- 左/右 端点分别向边里面访问点,假设左端点能访问a个点,右端点能访问b个点,那么能访问的点数就是min(a + b, 该边点数)
23+
- 统计完边,再统计点,只需要扫描所有点,根据最短路的端点值,判断是否不大于M,累加
24+
- 最短路复杂度是o(n^2),最短路中间有一个步骤,每一轮寻找当前最小的点开扩展,这一步骤是可以用一个堆来优化,复杂度是o(n log e),e是边的个数。这个做法留给大家做练习
25+
26+
代码:
27+
28+
```java
29+
class Solution {
30+
private static int MAX = 2000000000;
31+
32+
private class Edge {
33+
int src;
34+
int dest;
35+
int value;
36+
37+
public Edge(int src, int dest, int value) {
38+
this.src = src;
39+
this.dest = dest;
40+
this.value = value;
41+
}
42+
}
43+
44+
public int reachableNodes(int[][] edges, int M, int N) {
45+
List<Edge>[] edgeList = new List[N];
46+
for (int i = 0;i < edgeList.length;i++) {
47+
edgeList[i] = new ArrayList<Edge>();
48+
}
49+
50+
for (int i = 0;i < edges.length;i++) {
51+
edgeList[edges[i][0]].add(new Edge(edges[i][0], edges[i][1], edges[i][2] + 1));
52+
edgeList[edges[i][1]].add(new Edge(edges[i][1], edges[i][0], edges[i][2] + 1));
53+
}
54+
55+
int ret = 0;
56+
57+
boolean[] flag = new boolean[N];
58+
int[] min = new int[N];
59+
for (int i = 0;i < N;i++) {
60+
flag[i] = false;
61+
min[i] = MAX;
62+
}
63+
64+
min[0] = 0;
65+
while (true) {
66+
int idx = -1;
67+
for (int i = 0;i < N;i++) {
68+
if (!flag[i] && min[i] != MAX) {
69+
if (idx == -1 || min[i] < min[idx]) {
70+
idx = i;
71+
}
72+
}
73+
}
74+
if (idx == -1) {
75+
break;
76+
}
77+
78+
flag[idx] = true;
79+
for (int i = 0;i < edgeList[idx].size();i++) {
80+
Edge edge = edgeList[idx].get(i);
81+
if (!flag[edge.dest]) {
82+
min[edge.dest] = Math.min(min[edge.dest], min[edge.src] + edge.value);
83+
}
84+
}
85+
}
86+
87+
for (int i = 0;i < edges.length;i++) {
88+
if (min[edges[i][0]] + edges[i][2] <= M || min[edges[i][1]] + edges[i][2] <= M) {
89+
ret += edges[i][2];
90+
continue;
91+
}
92+
int left = 0, right = 0;
93+
if (min[edges[i][0]] <= M) {
94+
left = M - min[edges[i][0]];
95+
}
96+
if (min[edges[i][1]] <= M) {
97+
right = M - min[edges[i][1]];
98+
}
99+
if (left + right >= edges[i][2]) {
100+
ret += edges[i][2];
101+
} else {
102+
ret += left + right;
103+
}
104+
}
105+
106+
for (int i = 0;i < N;i++) {
107+
if (min[i] <= M) {
108+
ret++;
109+
}
110+
}
111+
112+
return ret;
113+
}
114+
}
115+
```
116+

0 commit comments

Comments
 (0)