💡 PS
[BOJ] 2406 안정적인 네트워크
date
May 3, 2022
slug
boj-2406
author
status
Public
tags
PS
크루스칼
summary
안정적인 네트워크 문제에 대한 풀이입니다.
type
Post
thumbnail
category
💡 PS
updatedAt
Aug 3, 2023 09:24 AM
언어
문제
풀이
크루스칼 알고리즘을 이용하여 문제를 풀었다.
p
배열은 부모가 누구인지 알려주는 배열이다. (p[a] = b
라면 a의 부모는 b)
find
를 할 때 path compression
(경로 압축)을 통해 parent
를 찾아낸 루트로 바꿔 버리면 중복 연산을 방지한다.본사 컴퓨터는 이미 연결되어 있기 때문에
adj
배열에 푸쉬하지 않는다.
코스트 오름차순으로 정렬해주고 go
함수에서 순차적으로 탐색하며 같은 그룹이 아니면 merge
하고 ans
벡터에 두 노드 정보를 저장한다. sm
은 최소 비용이다.코드
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; typedef pair<int, int> pii; struct info{ int c, s, e; }; int n, m; vector<info> adj; vector<int> v[1000]; int p[1000], sm = 0; vector<pii> ans; int find(int a) { if (p[a] == -1) return a; return p[a] = find(p[a]); } void merge(int a, int b) { a = find(a), b = find(b); if (a == b) return; p[b] = a; } void go() { for(int i = 0; i < adj.size(); i++) { if (find(adj[i].s) == find(adj[i].e)) continue; merge(adj[i].s, adj[i].e); ans.push_back({adj[i].s, adj[i].e}); sm += adj[i].c; } } int main() { memset(p, -1, sizeof(p)); scanf("%d %d", &n, &m); for(int a, b, i = 0; i < m; i++) { scanf("%d %d", &a, &b); a--; b--; v[a].push_back(b); v[b].push_back(a); if (find(a) == find(b)) continue; merge(a, b); } for(int i = 0; i < n; i++) { for(int a, j = 0; j < n; j++) { scanf("%d", &a); if (i >= j or i == 0 or j == 0) continue; adj.push_back({a, i, j}); } } sort(adj.begin(), adj.end(), [](info a, info b) {return a.c < b.c;}); go(); printf("%d %d\n", sm, ans.size()); for(pii i : ans) printf("%d %d\n", i.first+1, i.second+1); }