|
69 | 69 |
|
70 | 70 | <!-- 这里可写通用的实现逻辑 -->
|
71 | 71 |
|
72 |
| -最小生成树 + 并查集。先将所有边按照长度由小到大进行排序,循环遍历每条边,逐个加入到图中,当所有点达到一个连通状态时,退出循环,返回此时的总费用即可。 |
| 72 | +最小生成树问题。 |
73 | 73 |
|
74 |
| -模板 1——朴素并查集: |
| 74 | +设 n 表示点数,m 表示边数。 |
75 | 75 |
|
76 |
| -```python |
77 |
| -# 初始化,p存储每个点的父节点 |
78 |
| -p = list(range(n)) |
79 |
| - |
80 |
| -# 返回x的祖宗节点 |
81 |
| -def find(x): |
82 |
| - if p[x] != x: |
83 |
| - # 路径压缩 |
84 |
| - p[x] = find(p[x]) |
85 |
| - return p[x] |
86 |
| - |
87 |
| -# 合并a和b所在的两个集合 |
88 |
| -p[find(a)] = find(b) |
89 |
| -``` |
90 |
| - |
91 |
| -模板 2——维护 size 的并查集: |
92 |
| - |
93 |
| -```python |
94 |
| -# 初始化,p存储每个点的父节点,size只有当节点是祖宗节点时才有意义,表示祖宗节点所在集合中,点的数量 |
95 |
| -p = list(range(n)) |
96 |
| -size = [1] * n |
97 |
| - |
98 |
| -# 返回x的祖宗节点 |
99 |
| -def find(x): |
100 |
| - if p[x] != x: |
101 |
| - # 路径压缩 |
102 |
| - p[x] = find(p[x]) |
103 |
| - return p[x] |
| 76 | +**方法一:朴素 Prim 算法** |
104 | 77 |
|
105 |
| -# 合并a和b所在的两个集合 |
106 |
| -if find(a) != find(b): |
107 |
| - size[find(b)] += size[find(a)] |
108 |
| - p[find(a)] = find(b) |
109 |
| -``` |
| 78 | +时间复杂度 O(n²)。 |
110 | 79 |
|
111 |
| -模板 3——维护到祖宗节点距离的并查集: |
| 80 | +**方法二:Kruskal 算法** |
112 | 81 |
|
113 |
| -```python |
114 |
| -# 初始化,p存储每个点的父节点,d[x]存储x到p[x]的距离 |
115 |
| -p = list(range(n)) |
116 |
| -d = [0] * n |
117 |
| - |
118 |
| -# 返回x的祖宗节点 |
119 |
| -def find(x): |
120 |
| - if p[x] != x: |
121 |
| - t = find(p[x]) |
122 |
| - d[x] += d[p[x]] |
123 |
| - p[x] = t |
124 |
| - return p[x] |
125 |
| - |
126 |
| -# 合并a和b所在的两个集合 |
127 |
| -p[find(a)] = find(b) |
128 |
| -d[find(a)] = distance |
129 |
| -``` |
| 82 | +先将所有边按照长度由小到大进行排序,循环遍历每条边,逐个加入到图中,当所有点达到一个连通状态时,退出循环,返回此时的总费用即可。 |
130 | 83 |
|
131 | 84 | <!-- tabs:start -->
|
132 | 85 |
|
133 | 86 | ### **Python3**
|
134 | 87 |
|
135 | 88 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
136 | 89 |
|
| 90 | +```python |
| 91 | +class Solution: |
| 92 | + def minCostConnectPoints(self, points: List[List[int]]) -> int: |
| 93 | + INF = 0x3f3f3f3f |
| 94 | + n = len(points) |
| 95 | + g = [[0] * n for _ in range(n)] |
| 96 | + for i in range(n): |
| 97 | + for j in range(n): |
| 98 | + if i != j: |
| 99 | + x1, y1 = points[i] |
| 100 | + x2, y2 = points[j] |
| 101 | + g[i][j] = abs(x1 - x2) + abs(y1 - y2) |
| 102 | + dist = [INF] * n |
| 103 | + vis = [False] * n |
| 104 | + ans = 0 |
| 105 | + for i in range(n): |
| 106 | + t = -1 |
| 107 | + for j in range(n): |
| 108 | + if not vis[j] and (t == -1 or dist[t] > dist[j]): |
| 109 | + t = j |
| 110 | + if i: |
| 111 | + ans += dist[t] |
| 112 | + for j in range(n): |
| 113 | + dist[j] = min(dist[j], g[t][j]) |
| 114 | + vis[t] = True |
| 115 | + return ans |
| 116 | +``` |
| 117 | + |
137 | 118 | ```python
|
138 | 119 | class Solution:
|
139 | 120 | def minCostConnectPoints(self, points: List[List[int]]) -> int:
|
@@ -168,6 +149,46 @@ class Solution:
|
168 | 149 |
|
169 | 150 | <!-- 这里可写当前语言的特殊实现逻辑 -->
|
170 | 151 |
|
| 152 | +```java |
| 153 | +class Solution { |
| 154 | + private static final int INF = 0x3f3f3f3f; |
| 155 | + |
| 156 | + public int minCostConnectPoints(int[][] points) { |
| 157 | + int n = points.length; |
| 158 | + int[][] g = new int[n][n]; |
| 159 | + int[] dist = new int[n]; |
| 160 | + boolean[] vis = new boolean[n]; |
| 161 | + for (int i = 0; i < n; ++i) { |
| 162 | + for (int j = 0; j < n; ++j) { |
| 163 | + if (i != j) { |
| 164 | + int x1 = points[i][0], y1 = points[i][1]; |
| 165 | + int x2 = points[j][0], y2 = points[j][1]; |
| 166 | + g[i][j] = Math.abs(x1 - x2) + Math.abs(y1 - y2); |
| 167 | + } |
| 168 | + } |
| 169 | + } |
| 170 | + Arrays.fill(dist, INF); |
| 171 | + int ans = 0; |
| 172 | + for (int i = 0; i < n; ++i) { |
| 173 | + int t = -1; |
| 174 | + for (int j = 0; j < n; ++j) { |
| 175 | + if (!vis[j] && (t == -1 || dist[t] > dist[j])) { |
| 176 | + t = j; |
| 177 | + } |
| 178 | + } |
| 179 | + if (i > 0) { |
| 180 | + ans += dist[t]; |
| 181 | + } |
| 182 | + for (int j = 0; j < n; ++j) { |
| 183 | + dist[j] = Math.min(dist[j], g[t][j]); |
| 184 | + } |
| 185 | + vis[t] = true; |
| 186 | + } |
| 187 | + return ans; |
| 188 | + } |
| 189 | +} |
| 190 | +``` |
| 191 | + |
171 | 192 | ```java
|
172 | 193 | class Solution {
|
173 | 194 | private int[] p;
|
@@ -212,6 +233,48 @@ class Solution {
|
212 | 233 |
|
213 | 234 | ### **C++**
|
214 | 235 |
|
| 236 | +```cpp |
| 237 | +class Solution { |
| 238 | +public: |
| 239 | + const int inf = 0x3f3f3f3f; |
| 240 | + |
| 241 | + int minCostConnectPoints(vector<vector<int>>& points) { |
| 242 | + int n = points.size(); |
| 243 | + vector<vector<int>> g(n, vector<int>(n)); |
| 244 | + vector<int> dist(n, inf); |
| 245 | + vector<bool> vis(n); |
| 246 | + for (int i = 0; i < n; ++i) |
| 247 | + { |
| 248 | + for (int j = 0; j < n; ++j) |
| 249 | + { |
| 250 | + if (i != j) |
| 251 | + { |
| 252 | + int x1 = points[i][0], y1 = points[i][1]; |
| 253 | + int x2 = points[j][0], y2 = points[j][1]; |
| 254 | + g[i][j] = abs(x1 - x2) + abs(y1 - y2); |
| 255 | + } |
| 256 | + } |
| 257 | + } |
| 258 | + int ans = 0; |
| 259 | + for (int i = 0; i < n; ++i) |
| 260 | + { |
| 261 | + int t = -1; |
| 262 | + for (int j = 0; j < n; ++j) |
| 263 | + { |
| 264 | + if (!vis[j] && (t == -1 || dist[t] > dist[j])) |
| 265 | + { |
| 266 | + t = j; |
| 267 | + } |
| 268 | + } |
| 269 | + if (i) ans += dist[t]; |
| 270 | + for (int j = 0; j < n; ++j) dist[j] = min(dist[j], g[t][j]); |
| 271 | + vis[t] = true; |
| 272 | + } |
| 273 | + return ans; |
| 274 | + } |
| 275 | +}; |
| 276 | +``` |
| 277 | + |
215 | 278 | ```cpp
|
216 | 279 | class Solution {
|
217 | 280 | public:
|
@@ -253,6 +316,58 @@ public:
|
253 | 316 |
|
254 | 317 | ### **Go**
|
255 | 318 |
|
| 319 | +```go |
| 320 | +func minCostConnectPoints(points [][]int) int { |
| 321 | + n := len(points) |
| 322 | + inf := 0x3f3f3f3f |
| 323 | + g := make([][]int, n) |
| 324 | + dist := make([]int, n) |
| 325 | + vis := make([]bool, n) |
| 326 | + for i, p1 := range points { |
| 327 | + dist[i] = inf |
| 328 | + g[i] = make([]int, n) |
| 329 | + for j, p2 := range points { |
| 330 | + if i != j { |
| 331 | + x1, y1 := p1[0], p1[1] |
| 332 | + x2, y2 := p2[0], p2[1] |
| 333 | + g[i][j] = abs(x1-x2) + abs(y1-y2) |
| 334 | + } |
| 335 | + } |
| 336 | + } |
| 337 | + ans := 0 |
| 338 | + for i := 0; i < n; i++ { |
| 339 | + t := -1 |
| 340 | + for j := 0; j < n; j++ { |
| 341 | + if !vis[j] && (t == -1 || dist[t] > dist[j]) { |
| 342 | + t = j |
| 343 | + } |
| 344 | + } |
| 345 | + if i > 0 { |
| 346 | + ans += dist[t] |
| 347 | + } |
| 348 | + for j := 0; j < n; j++ { |
| 349 | + dist[j] = min(dist[j], g[t][j]) |
| 350 | + } |
| 351 | + vis[t] = true |
| 352 | + } |
| 353 | + return ans |
| 354 | +} |
| 355 | +
|
| 356 | +func min(a, b int) int { |
| 357 | + if a < b { |
| 358 | + return a |
| 359 | + } |
| 360 | + return b |
| 361 | +} |
| 362 | +
|
| 363 | +func abs(x int) int { |
| 364 | + if x < 0 { |
| 365 | + return -x |
| 366 | + } |
| 367 | + return x |
| 368 | +} |
| 369 | +``` |
| 370 | + |
256 | 371 | ```go
|
257 | 372 | var p []int
|
258 | 373 |
|
|
0 commit comments