Prim

进阶

Prim 从一个点出发贪心扩展,适合稠密图的最小生成树。

Prim

输入节点数和带权边,观察 Prim 从节点 0 扩展 MST 的过程。

AlgoAnim · Prim

待机

速度
待机
// 源代码
1int prim(int V, vector<vector<pair<int,int>>>& adj) {
2    vector<int> key(V, INT_MAX);
3    vector<bool> inMST(V, false);
4    key[0] = 0;
5    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<>> pq;
6    pq.push({0, 0});
7    int total = 0;
8    while (!pq.empty()) {
9        auto [w, u] = pq.top(); pq.pop();
10        if (inMST[u]) continue;
11        inMST[u] = true;
12        total += w;
13        for (auto [v, weight] : adj[u])
14            if (!inMST[v] && weight < key[v]) {
15                key[v] = weight;
16                pq.push({key[v], v});
17            }
18    }
19    return total;
20}

复杂度分析

时间 O((V+E) log V)
空间 O(V)
最优 O(V log V) 稠密图
最坏 O((V+E) log V)

算法讲解

Prim 从一个初始节点出发,维护一个"已在树中"的集合。

每轮从连接树内外的所有边中选权值最小的一条,将新节点加入树中。

用优先队列优化后时间复杂度为 O((V+E) log V),适合稠密图。

和 Kruskal 不同,Prim 是"加点法"而非"加边法",两者殊途同归。