[c++] 프림 알고리즘(Prim's Algorithm) 최소 신장 트리 알고리즘

프림 알고리즘은 그래프의 최소 신장 트리(Minimum Spanning Tree)를 찾기 위한 알고리즘 중 하나입니다. 최소 신장 트리는 그래프 내의 모든 정점을 포함하면서 어떤 코스트 함수가 정의된 경우에 그 값이 최소가 되는 트리입니다.

알고리즘 설명

프림 알고리즘은 아래와 같은 절차를 따릅니다:

  1. 시작 정점을 선택하고, 이 정점을 현재의 최소 신장 트리에 포함시킵니다.
  2. 현재의 최소 신장 트리에 속한 정점과 연결된 간선 중에서 가장 작은 가중치를 가진 간선을 선택합니다.
  3. 이 간선에 연결된 정점을 최소 신장 트리에 포함시킵니다.
  4. 위의 과정을 그래프 내의 모든 정점이 최소 신장 트리에 포함될 때까지 반복합니다.

프림 알고리즘은 주로 우선순위 큐(Priority Queue)를 사용하여 구현됩니다. 이를 통해 간선의 가중치를 기준으로 가장 작은 값을 선택할 수 있습니다.

C++ 예시

아래는 C++로 프림 알고리즘을 구현한 간단한 예시 코드입니다.

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

#define INF 0x3f3f3f3f

typedef pair<int, int> pii;

int prim(vector<vector<pii>>& graph) {
    int n = graph.size();
    vector<bool> visited(n, false);
    vector<int> dist(n, INF);
    priority_queue<pii, vector<pii>, greater<pii>> pq;

    int mst_cost = 0;
    pq.push({0, 0});
    dist[0] = 0;

    while (!pq.empty()) {
        int u = pq.top().second;
        pq.pop();

        if (visited[u]) continue;
        visited[u] = true;
        mst_cost += dist[u];

        for (auto& edge : graph[u]) {
            int v = edge.first;
            int weight = edge.second;
            if (!visited[v] && weight < dist[v]) {
                dist[v] = weight;
                pq.push({dist[v], v});
            }
        }
    }

    return mst_cost;
}

int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<pii>> graph(n);

    for (int i = 0; i < m; ++i) {
        int u, v, w;
        cin >> u >> v >> w;
        graph[u].push_back({v, w});
        graph[v].push_back({u, w});
    }

    int min_cost = prim(graph);
    
    cout << "Minimum Cost of Minimum Spanning Tree: " << min_cost << endl;
    return 0;
}

참고 자료