|
67 | 67 |
|
68 | 68 | <!-- 这里可写通用的实现逻辑 -->
|
69 | 69 |
|
| 70 | +**方法一:拓扑排序** |
| 71 | + |
| 72 | +我们可以先将 $edges$ 中的边转换成邻接表 $g$,其中 $g[i]$ 表示节点 $i$ 的所有邻接节点,用集合表示。 |
| 73 | + |
| 74 | +接下来,我们由外向内,逐层删除节点,直到最终只剩下一个环。具体做法如下: |
| 75 | + |
| 76 | +我们先找出所有度为 $1$ 的节点,将这些节点从图中删除,如果删除后,其邻接节点的度变为 $1$,则将其加入队列 $q$ 中。过程中,我们按顺序记录下所有被删除的节点,记为 $seq$;并且,我们用一个数组 $f$ 记录每个节点相邻的且更接近环的节点,即 $f[i]$ 表示节点 $i$ 的相邻且更接近环的节点。 |
| 77 | + |
| 78 | +最后,我们初始化一个长度为 $n$ 的答案数组 $ans$,其中 $ans[i]$ 表示节点 $i$ 到环中任意节点的最小距离,初始时 $ans[i] = 0$。然后,我们从 $seq$ 的末尾开始遍历,对于每个节点 $i$,我们可以由它的相邻节点 $f[i]$ 得到 $ans[i]$ 的值,即 $ans[i] = ans[f[i]] + 1$。 |
| 79 | + |
| 80 | +遍历结束后,返回答案数组 $ans$ 即可。 |
| 81 | + |
| 82 | +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为节点数。 |
| 83 | + |
| 84 | +相似题目: |
| 85 | + |
| 86 | +- [2603. 收集树中金币](/solution/2600-2699/2603.Collect%20Coins%20in%20a%20Tree/README.md) |
| 87 | + |
70 | 88 | <!-- tabs:start -->
|
71 | 89 |
|
72 | 90 | ### **Python3**
|
73 | 91 |
|
74 | 92 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
75 | 93 |
|
76 | 94 | ```python
|
77 |
| - |
| 95 | +class Solution: |
| 96 | + def distanceToCycle(self, n: int, edges: List[List[int]]) -> List[int]: |
| 97 | + g = defaultdict(set) |
| 98 | + for a, b in edges: |
| 99 | + g[a].add(b) |
| 100 | + g[b].add(a) |
| 101 | + q = deque(i for i in range(n) if len(g[i]) == 1) |
| 102 | + f = [0] * n |
| 103 | + seq = [] |
| 104 | + while q: |
| 105 | + i = q.popleft() |
| 106 | + seq.append(i) |
| 107 | + for j in g[i]: |
| 108 | + g[j].remove(i) |
| 109 | + f[i] = j |
| 110 | + if len(g[j]) == 1: |
| 111 | + q.append(j) |
| 112 | + g[i].clear() |
| 113 | + ans = [0] * n |
| 114 | + for i in seq[::-1]: |
| 115 | + ans[i] = ans[f[i]] + 1 |
| 116 | + return ans |
78 | 117 | ```
|
79 | 118 |
|
80 | 119 | ### **Java**
|
81 | 120 |
|
82 | 121 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
83 | 122 |
|
84 | 123 | ```java
|
| 124 | +class Solution { |
| 125 | + public int[] distanceToCycle(int n, int[][] edges) { |
| 126 | + Set<Integer>[] g = new Set[n]; |
| 127 | + Arrays.setAll(g, k -> new HashSet<>()); |
| 128 | + for (var e : edges) { |
| 129 | + int a = e[0], b = e[1]; |
| 130 | + g[a].add(b); |
| 131 | + g[b].add(a); |
| 132 | + } |
| 133 | + Deque<Integer> q = new ArrayDeque<>(); |
| 134 | + for (int i = 0; i < n; ++i) { |
| 135 | + if (g[i].size() == 1) { |
| 136 | + q.offer(i); |
| 137 | + } |
| 138 | + } |
| 139 | + int[] f = new int[n]; |
| 140 | + Deque<Integer> seq = new ArrayDeque<>(); |
| 141 | + while (!q.isEmpty()) { |
| 142 | + int i = q.poll(); |
| 143 | + seq.push(i); |
| 144 | + for (int j : g[i]) { |
| 145 | + g[j].remove(i); |
| 146 | + f[i] = j; |
| 147 | + if (g[j].size() == 1) { |
| 148 | + q.offer(j); |
| 149 | + } |
| 150 | + } |
| 151 | + } |
| 152 | + int[] ans = new int[n]; |
| 153 | + while (!seq.isEmpty()) { |
| 154 | + int i = seq.pop(); |
| 155 | + ans[i] = ans[f[i]] + 1; |
| 156 | + } |
| 157 | + return ans; |
| 158 | + } |
| 159 | +} |
| 160 | +``` |
| 161 | + |
| 162 | +### **C++** |
85 | 163 |
|
| 164 | +```cpp |
| 165 | +class Solution { |
| 166 | +public: |
| 167 | + vector<int> distanceToCycle(int n, vector<vector<int>>& edges) { |
| 168 | + unordered_set<int> g[n]; |
| 169 | + for (auto& e : edges) { |
| 170 | + int a = e[0], b = e[1]; |
| 171 | + g[a].insert(b); |
| 172 | + g[b].insert(a); |
| 173 | + } |
| 174 | + queue<int> q; |
| 175 | + for (int i = 0; i < n; ++i) { |
| 176 | + if (g[i].size() == 1) { |
| 177 | + q.push(i); |
| 178 | + } |
| 179 | + } |
| 180 | + int f[n]; |
| 181 | + int seq[n]; |
| 182 | + int k = 0; |
| 183 | + while (!q.empty()) { |
| 184 | + int i = q.front(); |
| 185 | + q.pop(); |
| 186 | + seq[k++] = i; |
| 187 | + for (int j : g[i]) { |
| 188 | + g[j].erase(i); |
| 189 | + f[i] = j; |
| 190 | + if (g[j].size() == 1) { |
| 191 | + q.push(j); |
| 192 | + } |
| 193 | + } |
| 194 | + g[i].clear(); |
| 195 | + } |
| 196 | + vector<int> ans(n); |
| 197 | + for (; k; --k) { |
| 198 | + int i = seq[k - 1]; |
| 199 | + ans[i] = ans[f[i]] + 1; |
| 200 | + } |
| 201 | + return ans; |
| 202 | + } |
| 203 | +}; |
| 204 | +``` |
| 205 | +
|
| 206 | +### **Go** |
| 207 | +
|
| 208 | +```go |
| 209 | +func distanceToCycle(n int, edges [][]int) []int { |
| 210 | + g := make([]map[int]bool, n) |
| 211 | + for i := range g { |
| 212 | + g[i] = map[int]bool{} |
| 213 | + } |
| 214 | + for _, e := range edges { |
| 215 | + a, b := e[0], e[1] |
| 216 | + g[a][b] = true |
| 217 | + g[b][a] = true |
| 218 | + } |
| 219 | + q := []int{} |
| 220 | + for i := 0; i < n; i++ { |
| 221 | + if len(g[i]) == 1 { |
| 222 | + q = append(q, i) |
| 223 | + } |
| 224 | + } |
| 225 | + f := make([]int, n) |
| 226 | + seq := []int{} |
| 227 | + for len(q) > 0 { |
| 228 | + i := q[0] |
| 229 | + q = q[1:] |
| 230 | + seq = append(seq, i) |
| 231 | + for j := range g[i] { |
| 232 | + delete(g[j], i) |
| 233 | + f[i] = j |
| 234 | + if len(g[j]) == 1 { |
| 235 | + q = append(q, j) |
| 236 | + } |
| 237 | + } |
| 238 | + g[i] = map[int]bool{} |
| 239 | + } |
| 240 | + ans := make([]int, n) |
| 241 | + for k := len(seq) - 1; k >= 0; k-- { |
| 242 | + i := seq[k] |
| 243 | + ans[i] = ans[f[i]] + 1 |
| 244 | + } |
| 245 | + return ans |
| 246 | +} |
86 | 247 | ```
|
87 | 248 |
|
88 | 249 | ### **TypeScript**
|
89 | 250 |
|
90 | 251 | ```ts
|
91 |
| - |
| 252 | +function distanceToCycle(n: number, edges: number[][]): number[] { |
| 253 | + const g: Set<number>[] = new Array(n).fill(0).map(() => new Set<number>()); |
| 254 | + for (const [a, b] of edges) { |
| 255 | + g[a].add(b); |
| 256 | + g[b].add(a); |
| 257 | + } |
| 258 | + const q: number[] = []; |
| 259 | + for (let i = 0; i < n; ++i) { |
| 260 | + if (g[i].size === 1) { |
| 261 | + q.push(i); |
| 262 | + } |
| 263 | + } |
| 264 | + const f: number[] = Array(n).fill(0); |
| 265 | + const seq: number[] = []; |
| 266 | + while (q.length) { |
| 267 | + const i = q.pop()!; |
| 268 | + seq.push(i); |
| 269 | + for (const j of g[i]) { |
| 270 | + g[j].delete(i); |
| 271 | + f[i] = j; |
| 272 | + if (g[j].size === 1) { |
| 273 | + q.push(j); |
| 274 | + } |
| 275 | + } |
| 276 | + g[i].clear(); |
| 277 | + } |
| 278 | + const ans: number[] = Array(n).fill(0); |
| 279 | + while (seq.length) { |
| 280 | + const i = seq.pop()!; |
| 281 | + ans[i] = ans[f[i]] + 1; |
| 282 | + } |
| 283 | + return ans; |
| 284 | +} |
92 | 285 | ```
|
93 | 286 |
|
94 | 287 | ### **...**
|
|
0 commit comments