알고리즘/HackerRank_문제풀이

[PS]#Roads and Libraries

코딩하는상후니 2022. 12. 3. 17:08

 


 

#include <bits/stdc++.h>

using namespace std;

#define PII pair<int, int>

int q, n, m, c_lib, c_road, parent[100001], rrank[100001], cnt[100001];

int Find(int x)
{
	if (parent[x] == x) return x;
	return parent[x] = Find(parent[x]);
}

void Union(int x, int y)
{
	int X = Find(x), Y = Find(y);
	if (X == Y) return;

	if (rrank[X] > rrank[Y]) swap(X, Y);

	parent[X] = Y;
	cnt[Y] += cnt[X] + 1;
	if (rrank[X] == rrank[Y]) ++rrank[Y];
}

long roadsAndLibraries(vector<PII> vec)
{
	if (c_lib <= c_road) return static_cast<long>(n) * static_cast<long>(c_lib);

	for (int i = 0; i < vec.size(); ++i)
	{
		int f = vec[i].first, s = vec[i].second;
		Union(f, s);
	}

	long ret = 0;
	for (int i = 1; i <= n; ++i)
	{
		if (parent[i] != i) continue;
		ret += (long)c_lib;
		ret += static_cast<long>(c_road) * static_cast<long>(cnt[i]);
	}
	return ret;
}
 

* 문제 풀이 과정

 
Disjoint set 알고리즘을 이용함으로써 싸이클 예방과 동시에 구역을 구별할 수 있기에 적절하다.
이를 이용해 문제에서 말하는 최소 건설 비용을 구할 수 있다.
( c_load 길 수리비용, c_lib 도서관 건설 비용 )
n 개의 도시에서 최소 1개의 도서관이 필요하고 길을 수리해서 다른 도시의 도서관을 다닐 수 있다.
모든 노드가 도서관을 갈 수 있게 하는 최소 비용을 구하는 것이 문제의 목적이다.
 
구역 구별은 parent[i] = i 일 때 판별 가능하고 Union 이 실행될 때 붙여지는 구역의 연결된 길의 갯수를 더해준다.
이 때, 합쳐지는 구역의 길의 갯수는 1개가 아닐 수 있다.
최적화를 위해 rank 를 구별해서 구현할 수도 있겠다.
 
또 한가지 조심해야할 것은 결과 값이 int 범위를 초과한다는 점이다.

 

 

 

 

 

 

'알고리즘 > HackerRank_문제풀이' 카테고리의 다른 글

[PS]#The Story of a Tree  (0) 2022.11.23
[PS]#Lily's Homework  (0) 2022.11.20
[PS]#Bear and Steady Gene  (0) 2022.11.20
[PS]#Ice Cream Parlor  (0) 2022.11.20
[PS]#Gridland Metro  (0) 2022.11.17