【图论】最小生成树

最小生成树

生成树

现在一张有 n 个点的联通无向图 G
G 的一个子图是一颗包含所有点的树
则称这颗树为原图 G 的生成树

简单来说就是用 n 1 条边将所有点连起来,这些边所形成的便是原图的生成树

最小生成树

如果把每条边加上边权,生成树的 n 1 条边的权值之和最小的被称为最小生成树
举个例子
最小生成树
其中的蓝边就是该图的最小生成树

最小生成树算法

最常见的有Kruskal和Prim
由于Prim堆优化实在是不如Kruskal来的方便简单,理解上也是Kruskal容易,所以直介绍Kruskal
Kruskal
生成树既然是一棵树,那么肯定不存在回路
这样就可以把边从小到大排序,之后依次循环往最小生成树中加边。
如果加入这条边后树中形成回路,则不加此边。
若树中已含有 n 1 条边便停止循环,这时的树就是最小生成树。
其中判断回路可以用并查集来实现。
加入一条边 ( u , v )
1. 如果 u v 已经在同一个集合之中,便是形成回路,不加此边。
2. 否则增加此边,将 u , v 合并。
主要代码:

scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i++)
        scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
sort(edge + 1, edge + m + 1);
for(int i = 1; i <= m; i++)
    if(Union(edge[i].u, edge[i].v))
        addedge(edge[i].u, edge[i].v, edge[i].w);

猜你喜欢

转载自blog.csdn.net/tle666/article/details/79584989