About 最小生成树:
1、定义:
在一张图中,选择n-1个边,是每一个点都被连通,得到的树就是这张图的最小生成树。
2、方法;
(1)prim
算法步骤:
1)从任意一点出发,选择离它最近、未被访问且与它直接相连的点;
2)更新它的周围的点的从一点到它的最短边权;
3)将所有点的mins加起来便是最小生成树的最小总边权。
for(int i = 1; i <= n; i++)
{
int k = 0, j, minn = 1 << 30;
for(j = 1; j <= n; j++)
{
if(!v[j] && mins[j] < minn)
k = j, minn = mins[j];
}
v[k] = 1;
for(j = 1; j <= n; j++)
{
if(!v[j] && g[k][j] < mins[j])
mins[j] = g[k][j];
}
}
int MST = 0;
for(int i = 1; i <= n; i++)
MST += mins[i];
(2)Kruskal
算法步骤:
1)将每一条边按边权从小到大排序
2)依次选一条边。
若该边可连接两个不同集合的点,则mst加上该边边权,并将两个集合合并。
3)当成功选择n-1条边后,算法结束。mst便是最小生成树的最小总边权
//w[i].s表示i号边的起点,w[i].e表示i号边的终点,w[i].l表示i号边的权值\
int find(int n)
{
if(father[n] != n)
father[n] = find(father[n]);
return father[n];
}
sort(w + 1, w + E + 1, cmp); //按w.l从小到大排序
int MST = 0;
for(int i = 1; i <= E; i++)
{
int a = find(w[i].s), b = find(w[i].e);
if(a == b) continue;
MST += w[i].l;
father[a] = b;
}