Prim O(n2)
/* 最小生成树不允许自环的存在
prim求最小生成树 和dijkstra有点像
1. dist是维护点到集合的距离
2. 每次选取到集合最近的点更新最短路
*/
const int INF = 0x3f3f3f3f;
...
...
int prim(){
memset(dis, 0x3f, sizeof dis);
int res = 0;
for(int i = 0; i < n; ++i) {
int t = -1;
for(int j = 1; j <= n; ++j)
if(!st[j] && (t == -1 || dis[t] > dis[j]))
t = j;
if(i && dis[t] == INF) return INF;
if(i) res += dis[t];
for(int j = 1; j <= n; ++j)
//点到集合的距离,和dijkstra不一样
dis[j] = min(dis[j], G[t][j]);
st[t] = true;
}
return res;
}
Kruskal O(mlogm) 适用于稀疏图
/*
1. 将边存入集合中,然后排序。
2. 从小到大取出,然后判断当前from to 是否在一个集合中(通过并查集实现)
*/
struct Edge {
int from, to, w;
bool operator<(const Edge &W) const {
return w < W.w;
}
}edges[M];
int find(int x){
if(x != fa[x])
fa[x] = find(fa[x]);
return fa[x];
}
int kruskal(){
sort(edges, edges+m);
for(int i = 1; i <= n; ++i) fa[i] = i;
int sum = 0, cnt = 0;
for(int i = 0; i < m; ++i){
int from = edges[i].from, to = edges[i].to, w = edges[i].w;
int fa1 = find(from), fa2 = find(to);
if(fa1 != fa2){
fa[fa1] = fa2;
sum += w;
cnt++;
}
}
if(cnt < n-1)
return 0x3f3f3f3f;
return sum;
}