본문 바로가기
CS(Computer Science)지식/[C++][코딩 테스트] 자료구조 및 알고리즘

백준 1197번: 최소 스패닝 트리 (C++)

by 엔지니어 청년 2024. 2. 2.

문제링크

https://www.acmicpc.net/problem/1197

풀이방법

해당 문제는 최소 신장 트리를 구하는 알고리즘을 사용하여 해결할 수 있다. 최소 신장 트리를 찾는 알고리즘에는 두 가지가 있다. 하나는 크루스칼 알고리즘 나머지 하나는 프림 알고리즘이다. 이 중 프림 알고리즘을 사용하여 해당 문제를 해결하였다. 최소 신장 트리를 찾는 알고리즘에 대한 개념이 없다면 아래 영상을 참고하자.

코드

#include <bits/stdc++.h>
using namespace std;

#define X first
#define Y second

int v, e;
vector<pair<int, int>> adj[10005];
// (비용, 정점 번호)
// chk[i] : i번째 정점이 최소 신장 트리에 속해있는가?
bool chk[10005];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    
    cin >> v >> e;
    for (int i = 0; i < e; i++)
    {
        int a, b, cost;
        cin >> a >> b >> cost;
        adj[a].push_back({ cost,b });
        adj[b].push_back({ cost,a });
    }
    
    // tuple<int,int,int> : {비용, 정점 1, 정점 2}
    priority_queue < tuple<int, int, int>, vector < tuple<int, int, int>>,
        greater<tuple<int, int, int>> > pq;

    chk[1] = 1;
    for (auto nxt : adj[1])
    {
        pq.push({ nxt.X,1,nxt.Y });
    }

    int cnt = 0;
    int ans = 0;
    while (cnt < v - 1)
    {
        int cost, a, b;
        tie(cost, a, b) = pq.top(); pq.pop();
        if (chk[b]) continue;
        ans += cost;
        chk[b] = 1;
        cnt++;
        for (auto nxt : adj[b]) {
            if (chk[nxt.Y]) continue;
            pq.push({ nxt.X,b,nxt.Y });
        }
    }
    cout << ans;
    return 0;
}