最小生成树问题

(1)什么是最小生成树?
给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树.

(2)定理
任何一棵最小生成树一定包含无向图中权值最小的边。

(3)Kruskal 算法

  • 将图的所有连接线去掉,只剩顶点
  • 从图的边集数组中找到权值最小的边,将边的两个顶点连接起来
  • 继续寻找权值最小的边,将两个顶点之间连接起来,如果选择的边使得最小生成树出现了环路,则放弃该边,选择权值次小的边
  • 直到所有的顶点都被连接在一起并且没有环路,最小生成树就生成了。
  • 时间复杂度:o(mlogm),m为边数。

1584. 连接所有点的最小费用


struct rec{ int  x, y, w; }edge[1000010];
bool operator<(rec a,rec b) 
{
    return a.w < b.w;
}
int f[1010];
int unionFind(int a){
    if (f[a] != a)
        return unionFind(f[a]);
    return a;
}
class Solution {
public:

int minCostConnectPoints(vector>& points) {
    int idx = 0;
    //求出所有的边的权值
    for (int i = 0; i < points.size();i++)
    for (int j = i + 1; j < points.size(); j++){
        edge[idx++] = { i, j, abs(points[i][0] - points[j][0]) + abs(points[i][1] - points[j][1]) };
    }
    //并查集初始化
    for (int i = 0; i < points.size(); i++)
        f[i] = i;
    
    sort(edge, edge + idx);
    int ans = 0;
        for (int i = 0; i < idx; i++){
            int u = unionFind(edge[i].x) ;
            int v = unionFind(edge[i].y) ;
            if (u != v){
                f[u] = v;
                ans += edge[i].w;
            }
        }
    return ans;
}
};

可以理解成,在不同的城市建造铁路,构成联通方案中的最小花费。

你可能感兴趣的:(最小生成树问题)