|
45 | 45 |
|
46 | 46 | <!-- 这里可写通用的实现逻辑 -->
|
47 | 47 |
|
| 48 | +**方法一:枚举删除的边 + BFS** |
| 49 | + |
| 50 | +我们先根据数组 $edges$ 构建出邻接表 $g$,其中 $g[u]$ 表示顶点 $u$ 的所有邻接点。 |
| 51 | + |
| 52 | +接下来,我们枚举双向边 $(u, v)$,如果删除该边后,从顶点 $u$ 到顶点 $v$ 的路径依然存在,则包含该边的最短环的长度为 $dist[v] + 1$,其中 $dist[v]$ 表示从顶点 $u$ 到顶点 $v$ 的最短路径长度。我们取所有这样的环的最小值即可。 |
| 53 | + |
| 54 | +时间复杂度 $O(m^2)$,空间复杂度 $O(m + n)$。其中 $m$ 和 $n$ 分别为数组 $edges$ 的长度以及顶点数。 |
| 55 | + |
| 56 | +**方法二:枚举点 + BFS** |
| 57 | + |
| 58 | +与方法一类似,我们先根据数组 $edges$ 构建出邻接表 $g$,其中 $g[u]$ 表示顶点 $u$ 的所有邻接点。 |
| 59 | + |
| 60 | +接下来,我们枚举顶点 $u$,如果从顶点 $u$ 出发,有两条路径都到达了顶点 $v$,说明当前找到了一个环,长度为两条路径的长度之和。我们取所有这样的环的最小值即可。 |
| 61 | + |
| 62 | +时间复杂度 $O(m \times n)$,空间复杂度 $O(m + n)$。其中 $m$ 和 $n$ 分别为数组 $edges$ 的长度以及顶点数。 |
| 63 | + |
48 | 64 | <!-- tabs:start -->
|
49 | 65 |
|
50 | 66 | ### **Python3**
|
51 | 67 |
|
52 | 68 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
53 | 69 |
|
| 70 | +```python |
| 71 | +class Solution: |
| 72 | + def findShortestCycle(self, n: int, edges: List[List[int]]) -> int: |
| 73 | + def bfs(u: int, v: int) -> int: |
| 74 | + dist = [inf] * n |
| 75 | + dist[u] = 0 |
| 76 | + q = deque([u]) |
| 77 | + while q: |
| 78 | + i = q.popleft() |
| 79 | + for j in g[i]: |
| 80 | + if (i, j) != (u, v) and (j, i) != (u, v) and dist[j] == inf: |
| 81 | + dist[j] = dist[i] + 1 |
| 82 | + q.append(j) |
| 83 | + return dist[v] + 1 |
| 84 | + |
| 85 | + g = defaultdict(set) |
| 86 | + for u, v in edges: |
| 87 | + g[u].add(v) |
| 88 | + g[v].add(u) |
| 89 | + ans = min(bfs(u, v) for u, v in edges) |
| 90 | + return ans if ans < inf else -1 |
| 91 | +``` |
| 92 | + |
54 | 93 | ```python
|
55 | 94 | class Solution:
|
56 | 95 | def findShortestCycle(self, n: int, edges: List[List[int]]) -> int:
|
@@ -80,6 +119,48 @@ class Solution:
|
80 | 119 |
|
81 | 120 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
82 | 121 |
|
| 122 | +```java |
| 123 | +class Solution { |
| 124 | + private List<Integer>[] g; |
| 125 | + private final int inf = 1 << 30; |
| 126 | + |
| 127 | + public int findShortestCycle(int n, int[][] edges) { |
| 128 | + g = new List[n]; |
| 129 | + Arrays.setAll(g, k -> new ArrayList<>()); |
| 130 | + for (var e : edges) { |
| 131 | + int u = e[0], v = e[1]; |
| 132 | + g[u].add(v); |
| 133 | + g[v].add(u); |
| 134 | + } |
| 135 | + int ans = inf; |
| 136 | + for (var e : edges) { |
| 137 | + int u = e[0], v = e[1]; |
| 138 | + ans = Math.min(ans, bfs(u, v)); |
| 139 | + } |
| 140 | + return ans < inf ? ans : -1; |
| 141 | + } |
| 142 | + |
| 143 | + private int bfs(int u, int v) { |
| 144 | + int[] dist = new int[g.length]; |
| 145 | + Arrays.fill(dist, inf); |
| 146 | + dist[u] = 0; |
| 147 | + Deque<Integer> q = new ArrayDeque<>(); |
| 148 | + q.offer(u); |
| 149 | + while (!q.isEmpty()) { |
| 150 | + int i = q.poll(); |
| 151 | + for (int j : g[i]) { |
| 152 | + if ((i == u && j == v) || (i == v && j == u) || dist[j] != inf) { |
| 153 | + continue; |
| 154 | + } |
| 155 | + dist[j] = dist[i] + 1; |
| 156 | + q.offer(j); |
| 157 | + } |
| 158 | + } |
| 159 | + return dist[v] + 1; |
| 160 | + } |
| 161 | +} |
| 162 | +``` |
| 163 | + |
83 | 164 | ```java
|
84 | 165 | class Solution {
|
85 | 166 | private List<Integer>[] g;
|
@@ -126,6 +207,45 @@ class Solution {
|
126 | 207 |
|
127 | 208 | ### **C++**
|
128 | 209 |
|
| 210 | +```cpp |
| 211 | +class Solution { |
| 212 | +public: |
| 213 | + int findShortestCycle(int n, vector<vector<int>>& edges) { |
| 214 | + vector<vector<int>> g(n); |
| 215 | + for (auto& e : edges) { |
| 216 | + int u = e[0], v = e[1]; |
| 217 | + g[u].push_back(v); |
| 218 | + g[v].push_back(u); |
| 219 | + } |
| 220 | + const int inf = 1 << 30; |
| 221 | + auto bfs = [&](int u, int v) -> int { |
| 222 | + int dist[n]; |
| 223 | + fill(dist, dist + n, inf); |
| 224 | + dist[u] = 0; |
| 225 | + queue<int> q{{u}}; |
| 226 | + while (!q.empty()) { |
| 227 | + int i = q.front(); |
| 228 | + q.pop(); |
| 229 | + for (int j : g[i]) { |
| 230 | + if ((i == u && j == v) || (i == v && j == u) || dist[j] != inf) { |
| 231 | + continue; |
| 232 | + } |
| 233 | + dist[j] = dist[i] + 1; |
| 234 | + q.push(j); |
| 235 | + } |
| 236 | + } |
| 237 | + return dist[v] + 1; |
| 238 | + }; |
| 239 | + int ans = inf; |
| 240 | + for (auto& e : edges) { |
| 241 | + int u = e[0], v = e[1]; |
| 242 | + ans = min(ans, bfs(u, v)); |
| 243 | + } |
| 244 | + return ans < inf ? ans : -1; |
| 245 | + } |
| 246 | +}; |
| 247 | +``` |
| 248 | +
|
129 | 249 | ```cpp
|
130 | 250 | class Solution {
|
131 | 251 | public:
|
@@ -170,6 +290,54 @@ public:
|
170 | 290 |
|
171 | 291 | ### **Go**
|
172 | 292 |
|
| 293 | +```go |
| 294 | +func findShortestCycle(n int, edges [][]int) int { |
| 295 | + g := make([][]int, n) |
| 296 | + for _, e := range edges { |
| 297 | + u, v := e[0], e[1] |
| 298 | + g[u] = append(g[u], v) |
| 299 | + g[v] = append(g[v], u) |
| 300 | + } |
| 301 | + const inf = 1 << 30 |
| 302 | + bfs := func(u, v int) int { |
| 303 | + dist := make([]int, n) |
| 304 | + for i := range dist { |
| 305 | + dist[i] = inf |
| 306 | + } |
| 307 | + dist[u] = 0 |
| 308 | + q := []int{u} |
| 309 | + for len(q) > 0 { |
| 310 | + i := q[0] |
| 311 | + q = q[1:] |
| 312 | + for _, j := range g[i] { |
| 313 | + if (i == u && j == v) || (i == v && j == u) || dist[j] != inf { |
| 314 | + continue |
| 315 | + } |
| 316 | + dist[j] = dist[i] + 1 |
| 317 | + q = append(q, j) |
| 318 | + } |
| 319 | + } |
| 320 | + return dist[v] + 1 |
| 321 | + } |
| 322 | + ans := inf |
| 323 | + for _, e := range edges { |
| 324 | + u, v := e[0], e[1] |
| 325 | + ans = min(ans, bfs(u, v)) |
| 326 | + } |
| 327 | + if ans < inf { |
| 328 | + return ans |
| 329 | + } |
| 330 | + return -1 |
| 331 | +} |
| 332 | + |
| 333 | +func min(a, b int) int { |
| 334 | + if a < b { |
| 335 | + return a |
| 336 | + } |
| 337 | + return b |
| 338 | +} |
| 339 | +``` |
| 340 | + |
173 | 341 | ```go
|
174 | 342 | func findShortestCycle(n int, edges [][]int) int {
|
175 | 343 | g := make([][]int, n)
|
@@ -222,6 +390,42 @@ func min(a, b int) int {
|
222 | 390 |
|
223 | 391 | ### **TypeScript**
|
224 | 392 |
|
| 393 | +```ts |
| 394 | +function findShortestCycle(n: number, edges: number[][]): number { |
| 395 | + const g: number[][] = new Array(n).fill(0).map(() => []); |
| 396 | + for (const [u, v] of edges) { |
| 397 | + g[u].push(v); |
| 398 | + g[v].push(u); |
| 399 | + } |
| 400 | + const inf = 1 << 30; |
| 401 | + let ans = inf; |
| 402 | + const bfs = (u: number, v: number) => { |
| 403 | + const dist: number[] = new Array(n).fill(inf); |
| 404 | + dist[u] = 0; |
| 405 | + const q: number[] = [u]; |
| 406 | + while (q.length) { |
| 407 | + const i = q.shift()!; |
| 408 | + for (const j of g[i]) { |
| 409 | + if ( |
| 410 | + (i == u && j == v) || |
| 411 | + (i == v && j == u) || |
| 412 | + dist[j] != inf |
| 413 | + ) { |
| 414 | + continue; |
| 415 | + } |
| 416 | + dist[j] = dist[i] + 1; |
| 417 | + q.push(j); |
| 418 | + } |
| 419 | + } |
| 420 | + return 1 + dist[v]; |
| 421 | + }; |
| 422 | + for (const [u, v] of edges) { |
| 423 | + ans = Math.min(ans, bfs(u, v)); |
| 424 | + } |
| 425 | + return ans < inf ? ans : -1; |
| 426 | +} |
| 427 | +``` |
| 428 | + |
225 | 429 | ```ts
|
226 | 430 | function findShortestCycle(n: number, edges: number[][]): number {
|
227 | 431 | const g: number[][] = new Array(n).fill(0).map(() => []);
|
|
0 commit comments