← Назад к графовым алгоритмам

Алгоритм Прима

Построение минимального остовного дерева (MST)

🐍 Python
import heapq

n = int(input())
A = [list(map(int, input().split())) for _ in range(n)]
used = [0] * n
Q = []
D = [10**18] * n
G = []
e = 0

D[0] = 0
heapq.heappush(Q, (0, 0, 0))

while Q and e < n:
    w, a, b = heapq.heappop(Q)
    if used[b]:
        continue
    used[b] = 1
    e += 1
    G.append([a, b, w])
    for i in range(n):
        if not used[i]:
            weight = ((A[b][0] - A[i][0])**2 + (A[b][1] - A[i][1])**2)**0.5
            if weight < D[i]:
                D[i] = weight
                heapq.heappush(Q, (weight, b, i))

z = 0
for a, b, w in G:
    z += w
print(z)
⚙️ C++
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    
    vector<pair<double, double>> A(n);
    for (int i = 0; i < n; i++) {
        cin >> A[i].first >> A[i].second;
    }
    
    vector<int> used(n, 0);
    priority_queue<tuple<double, int, int>,
                   vector<tuple<double, int, int>>,
                   greater<tuple<double, int, int>>> Q;
    vector<double> D(n, 1e18);
    vector<tuple<int, int, double>> G;
    int e = 0;
    
    D[0] = 0;
    Q.push({0, 0, 0});
    
    while (!Q.empty() && e < n) {
        auto [w, a, b] = Q.top();
        Q.pop();
        if (used[b]) continue;
        used[b] = 1;
        e++;
        G.push_back({a, b, w});
        for (int i = 0; i < n; i++) {
            if (!used[i]) {
                double dx = A[b].first - A[i].first;
                double dy = A[b].second - A[i].second;
                double weight = sqrt(dx*dx + dy*dy);
                if (weight < D[i]) {
                    D[i] = weight;
                    Q.push({weight, b, i});
                }
            }
        }
    }
    
    double z = 0;
    for (auto [a, b, w] : G) {
        z += w;
    }
    cout << fixed << setprecision(10) << z << endl;
    
    return 0;
}

Как работает алгоритм Прима?

Алгоритм Прима — это жадный алгоритм для построения минимального остовного дерева (MST) во взвешенном неориентированном графе.

Алгоритм использует приоритетную очередь (кучу) для выбора минимального ребра:

В данной реализации координаты вершин задаются на плоскости, а вес ребра — это евклидово расстояние между точками.

Алгоритм гарантирует, что на каждом шаге добавляется ребро с минимальным весом, соединяющее построенную часть с непосещённой вершиной.

Временная сложность: O(m log n) — с использованием приоритетной очереди, где m — количество рёбер.

Дополнительная память: O(n + m).

Формат ввода и вывода

Ввод:

Вывод:

Пример ввода:

4
0 0
1 0
0 1
1 1

Здесь:
n=4 (вершины в углах квадрата)
Ребра: расстояние между вершинами 0-1 = 1, 0-2 = 1, 1-3 = 1, 2-3 = 1, диагонали ≈1.414

Вывод: 3 (минимальное остовное дерево из трёх рёбер по 1)

Попробовать алгоритм Прима онлайн

Введите координаты вершин:

Результат появится здесь...