Kruskal’s Algorithm
- 每次添加一条边到T中
- 按cost的非降序选边,且不构成环
可以用min heap来存边,以简化找权值最小的边的过程
- Initialize: O(e)
- the next edge to be chosen or deleted: O(loge)
- worst case of this process: O(eloge+e)
If the graph is represented by adj matrix or adj list, its representation should be converted to edges array which is expressed as (u,v,weight)
判断新加的点是否会导致形成一个环
本质上是看u,v是否在同一个component
- 并查集
把每个component存储一个set
s1 = find(u);
s2 = find(v);
if(s1 != s2) union(s1,s2);
#include <vector>
#include <algorithm>
using namespace std;
#define MAXV 1000
#define INF 1e9
struct edge {
int u, v;
int cost;
} E[MAXV];
bool cmp(edge a, edge b) {
return a.cost < b.cost;
}
int father[MAXV];
int findFather(int x) {
if (x == father[x])
return x;
int z = findFather(father[x]);
father[x] = z;
return z;
}
int kruskal(int n, int m) {
//n: num of v m:num of e
int ans = 0, numE = 0;
for (int i = 0; i < n; i++) {
father[i] = i;
}
sort(E, E + m, cmp);
for (int i = 0; i < m; i++) {
int faU = findFather(E[i].u);
int faV = findFather(E[i], v);
if (faU != faV) {
father[faU] = faV;
ans += E[i].cost;
numE++;
if (numE == n - 1)
break;
}
}
if (numE != n - 1)
return -1;
else
return ans;
}
Prim’s Algorithm
想法
- Begin with a tree T that contains an arbitrary single vertex.
- Add a least-cost edge (u,v) to T such that T∪{(u,v)} is kept as a tree. Note that edge (u,v) is such that exactly one of u and v is in T.
- Repeat this edge-addition step until T contains n-1 edges.
实现
#include <vector>
using namespace std;
#define MAXV 1000
#define INF 1e9
struct Node {
int v, dis;
};
vector<Node> adj[MAXV];
int n;
int d[MAXV];
bool vis[MAXV] = {false};
int prim() {
fill(d, d + MAXV, INF);
d[0] = 0;
int ans = 0;
for (int i = 0; i < n ; i++) {
int u = -1, MIN = INF;
for (int j = 0; j < n; j++) {
if (vis[j] == false && d[j] < MIN) {
u = j;
MIN = d[j];
}
}
if (u == -1)
return -1;
vis[u] = true;
ans += d[u];
for (int j = 0; j < adj[u].size(); j++) {
int v = adj[u][j].v;
if (vis[v] == false && adj[u][j].dis < d[v]) {
d[v] = G[u][v];
}
}
}
return ans;
}
时间复杂度:
普里姆算法的时间复杂度为O(n2),与网中的边数无关,因此适用于求稠密网的最小生成树。