전형적인 MST 프림 문제
https://www.acmicpc.net/problem/1922
V는 최대 1,000인데 E는 최대 100,000이니까 E >= VlogV를 기준으로
즉 100,000 >= 1000 * 16.6이므로 크로스칼보단 프림이 유리하다.
근데 정작 프림으로 풀고나서 다른 사람들 제출한 기록 보니까 크루스칼로 푼 사람들이랑 비슷하거나 오히려 느렸다....
그냥 프림 한번 써봤다는 의의로 기록 남긴다.
하나 주의할 점은 입력할때 { from, to, cost }에 { 1, 2, 10 }은 들어오는데 { 2, 1, 10 }은 안들어와서 입력받을때 둘 다 내가 넣어줘야 한다는 점이다.
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false); cin.tie(NULL);
int N, M;
cin >> N >> M;
// line[1]에는 1과 인접한 간선들의 정보가 들어감
// line[1][0] 은 1에 인접된 첫번째 간선의 정보이며 to, cost 순서인 pair객체
vector<vector<pair<int, int>>> lines(N + 1); // 정점을 1번부터 쓰니까 N + 1
int from, to, cost;
for (int i = 0; i < M; i++) {
cin >> from >> to >> cost;
lines[from].push_back({ to, cost });
lines[to].push_back({ from, cost }); // 반대로 가도 비용 같으니 넣어주기
}
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;
vector<bool> selected(N + 1, false);
selected[1] = true; // 시작점 무난하게 1번으로
for (auto p : lines[1]) { // 1번에 연결된 정점들 정보 업데이트
int adj_vertex = p.first;
int distance_to_adj = p.second;
pq.push({ distance_to_adj, adj_vertex }); // dist로 정렬하기 위해 순서 반대로
}
int answer = 0;
while (pq.size()) {
int distance_to_this = pq.top().first;
int this_vertex = pq.top().second;
pq.pop();
if (selected[this_vertex]) continue;
selected[this_vertex] = true; // 가장 가까운 곳 선택하고
for (auto p : lines[this_vertex]) { // 이 정점에서의 거리 업데이트
int adj_vertex = p.first;
int distance_to_adj = p.second;
if(!selected[adj_vertex]) pq.push({ distance_to_adj, adj_vertex });
}
answer += distance_to_this;
}
cout << answer;
return 0;
}