1. 程式人生 > 其它 >leecode.1584. 連線所有點的最小費用

leecode.1584. 連線所有點的最小費用

技術標籤:leecode-樹

題目

給你一個points 陣列,表示 2D 平面上的一些點,其中 points[i] = [xi, yi] 。

連線點 [xi, yi] 和點 [xj, yj] 的費用為它們之間的 曼哈頓距離 :|xi - xj| + |yi - yj| ,其中 |val| 表示 val 的絕對值。

請你返回將所有點連線的最小總費用。只有任意兩點之間 有且僅有 一條簡單路徑時,才認為所有點都已連線。

示例

在這裡插入圖片描述
輸入:points = [[0,0],[2,2],[3,10],[5,2],[7,0]]
輸出:20
解釋:
在這裡插入圖片描述
我們可以按照上圖所示連線所有點得到最小總費用,總費用為 20 。

注意到任意兩個點之間只有唯一一條路徑互相到達。

提示:

1 <= points.length <= 1000
-106 <= xi, yi <= 106
所有點 (xi, yi) 兩兩不同。

思路

  • 因為這道題目中的資料範圍是1e3,n^2的複雜度不會掛。
  • 首先因為兩個點之間存在距離,我們將所有的距離構成一個無向完全圖,然後我們使用prim演算法來計算這個完全無向圖的最小生成樹。
  • 使用一個dis陣列來儲存不同點對之間的距離。使用一個vis陣列來標記目前的點是否已經加到點集裡面,使用一個minDis陣列更新現有點集到剩餘點的距離.

程式碼

const int maxn = 1e3 + 10
; class Solution { public: int minCostConnectPoints(vector<vector<int>>& points) { int dis[maxn][maxn] = {0}, n = points.size(); if(n == 1) return 0; vector<int> minDis(n, 0x3f3f3f3f); bool vis[maxn] = {false}; for(int i = 0;i < n;i++)
{ for(int j = i + 1;j < n;j++) dis[i][j] = dis[j][i] = abs(points[i][0] - points[j][0]) + abs(points[i][1] - points[j][1]); } int ans = 0; for(int i = 0;i < n;i++){ int t = -1;//哨兵,來標記最小距離的下標的 for(int j = 0;j < n;j++){ if(!vis[j] && (t == -1 || minDis[t] > minDis[j])) t = j;//t==-1要放在前面 } vis[t] = true; if(i) ans += minDis[t];//跳過第一次還沒有更新minDis的情況 for(int j = 0;j < n;j++){ if(!vis[j]) //在已知的點集裡面重新更新minDis的大小 minDis[j] = min(minDis[j], dis[t][j]); } } return ans; } };