LeetCode 1584. 连接所有点的最小费用
Kruskal 更加适合稀疏图
const int N = 5e5 + 10;
struct Edge
{
int a, b, w;
bool operator < (Edge& e)
{
return w < e.w;
}
}e[N];
class Solution {
public:
int p[N];
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
int kruskal(int n)
{
sort(e, e + n);
int res = 0, cnt = 0;
for(int i = 0; i < n; i ++)
{
int a = e[i].a, b = e[i].b, w = e[i].w;
int pa = find(a), pb = find(b);
if(pa != pb)
{
p[pa] = pb;
cnt ++;
res += w;
}
if(cnt == n - 1) break;
}
return res;
}
int minCostConnectPoints(vector<vector<int>>& points) {
int n = points.size();
for(int i = 0; i <= n; i ++) p[i] = i;
int idx = 0;
for(int i = 0; i < n; i ++)
for(int j = i + 1; j < n; j ++)
{
int d = abs(points[i][0] - points[j][0]) + abs(points[i][1] - points[j][1]);
e[idx ++ ] = {i, j, d};
}
return kruskal(idx);
}
};
Prim 更加适合稠密图
const int N = 1010, INF = 0x3f3f3f3f;
class Solution {
public:
int g[N][N];
int dist[N];
bool st[N] = {false};
int prim(int n)
{
memset(dist, 0x3f, sizeof dist);
int res = 0;
for(int i = 0; i < n; i ++)
{
int t = -1;
for(int j = 0; j < n; j ++)
if(!st[j] && (t == -1 || dist[j] < dist[t]))
t = j;
if(i && dist[t] == INF) return INF;
if(i) res += dist[t];
st[t] = true;
for(int i = 0; i < n; i ++)
dist[i] = min(dist[i], g[t][i]);
}
return res;
}
int minCostConnectPoints(vector<vector<int>>& points) {
int n = points.size();
memset(g, 0x3f, sizeof g);
for(int i = 0; i < n; i ++)
for(int j = i + 1; j < n; j ++)
{
int d = abs(points[i][0] - points[j][0]) + abs(points[i][1] - points[j][1]);
g[i][j] = d;
g[j][i] = d;
}
return prim(n);
}
};