给定一个无向图,如果它的某个子图中任意两个顶点都互相连通并且是一棵树,那么这课树就是生成树。如果边上有权值,那么使得边权和最小的生成树叫做最小生成树(MST, Minimum Spanning Tree)。
(1)Prime算法
CODE01
void prim()
{
int mincost[MAXVEX];
bool used[MAXVEX];
fill(mincost, mincost + V,INF);
fill(used, used + V,false);
mincost[0] = 0;
int res = 0;
while (true)
{
int v = -1,mins=INF;
for (int u = 0; u < V; ++u)
{
if (!used[u] && mincost[u] < mins)
{
mins=mincost[u];
v = u;
}
}
if (v == -1)break;
used[v] = true;
res += mincost[v];
for (int u = 0; u < G2[v].size(); ++u)
{
edge e = G2[v][u];
mincost[e.to] = min(mincost[e.to], e.cost);
}
}
printf("%d\n", res);
}
(2)Kruskal算法
CODE02
用到的头文件是并查集的实现,请看本博客的文章并查集
#include"DisjointSet.h"
bool comp(const edge &e1, const edge &e2)
{
return e1.cost < e2.cost;
}
void kruskal()
{
edge es[MAXVEX];
DisjointSet D;
int k = 0;
for (int i = 0; i < V; ++i)
{
for (int j = 0; j < G2[i].size(); ++j)
{
es[k].from = i;
es[k].to = G2[i][j].to;
es[k].cost = G2[i][j].cost;
++k;
}
}
for (int i = 0; i < k; ++i)
{
printf("%d %d %d\n", es[i].from, es[i].to, es[i].cost);
}
printf("\n");
sort(es, es + k, comp);
for (int i = 0; i < k; ++i)
{
printf("%d %d %d\n", es[i].from, es[i].to, es[i].cost);
}
printf("\n");
int res = 0;
D.init(V);
for (int i = 0; i < k; ++i)
{
edge e = es[i];
if (!D.same(e.from, e.to))
{
D.unite(e.from, e.to);
res += e.cost;
}
}
printf("%d\n", res);
}