图论---Prim堆优化(稀疏图)

  • 题目通常会提示数据范围

    • 若 V ≤ 500,两种方法均可(朴素Prim更稳)。

    • 若 V ≤ 1e5,必须用优先队列Prim + vector 存图。

#include 
#include 
#include 
#include 
using namespace std;
 
const int N = 510, INF = 0x3f3f3f3f;
typedef pair PII; // (distance, node)
 
int n, m;
vector adj[N]; // 邻接表
int dist[N];        // 存储各点到生成树的最小距离
bool st[N];         // 标记是否已加入生成树
 
int prim() {
    memset(dist, 0x3f, sizeof dist);
    priority_queue, greater> heap; // 小根堆
 
    heap.push({0, 1}); // 从节点 1 开始
    dist[1] = 0;
 
    int res = 0, cnt = 0; // cnt 记录已加入生成树的节点数
    while (!heap.empty()) {
        auto [d, u] = heap.top();
        heap.pop();
 
        if (st[u]) continue; // 已加入生成树,跳过
        st[u] = true;
        res += d;
        cnt++;
 
        // 遍历 u 的所有邻边
        for (auto [v, w] : adj[u]) {
            if (!st[v] && w < dist[v]) {
                dist[v] = w;
                heap.push({dist[v], v});
            }
        }
    }
 
    return cnt == n ? res : INF; // 如果生成树包含所有节点,返回总权重;否则返回 INF
}
 
int main() {
    cin >> n >> m;
    while (m--) {
        int a, b, c;
        cin >> a >> b >> c;
        adj[a].push_back({b, c});
        adj[b].push_back({a, c}); // 无向图
    }
 
    int t = prim();
    if (t == INF) puts("impossible");
    else cout << t << endl;
 
    return 0;
}

你可能感兴趣的:(图论,算法)