본문 바로가기

알고리즘/SWEA

6855

static int N, K;
static int house[100000];
static int between[100000];

static int cmp(const void * p1, const void * p2)
{
	int n1 = *(int *)p1;
	int n2 = *(int *)p2;
	
	return n1 - n2;
}

static int solution(void)
{
	int ret = 0;

	scanf("%d %d", &N, &K);
	scanf("%d", &house[0]);

	for (int i = 1; i < N; i++)
	{
		scanf("%d", &house[i]);
		between[i - 1] = house[i] - house[i - 1];
	}

	if (K >= N)
		return 0;
	if (K == 1)
		return house[N - 1] - house[0];

	qsort(between, N - 1, sizeof(int), cmp);
	for (int i = 0; i < N - K; i++)
		ret += between[i];

	return ret;
}

이 문제는 풀지는 못했다. 애초에 문제 이해를 잘못하고 있던 것도 있지만, 최소신장트리의 개념이 적용되는 것도 몰랐다.

 

그래서 그 풀이에 대한 내용을 정리해볼까 한다.

일단 두개의 조건에 대한 반환 값은 자명하다.

 

다음은 가장 일반적인 경우에 대한 모델이다.

5개의 집이 있다. 발전소 2개를 건설 할 때, 집 사이에 발전소 하나를 세우는 것 보다는 해당 집이 위치한 곳에 발전소를 세우면 해당 위치에 집으로 전선을 설치 할 필요는 없다.

그래서 나머지 하나의 발전소도 집이 있는 위치에 설치하는 것이 설치한 전선의 길이를 줄이는데 효과적이다.

 

또한 인접한 두 집 사이를 이으면 이는 하나의 최소신장트리가 된다.

 

20 <-20-> 40 <-30-> 70 <-20-> 90 <-60-> 150

 

연결 그래프이고, 20 에서 150을 바로 잇는 것 보다는 이런식으로 잇는 것이 전체 가중치의 합을 최소로 하기 때문이다.

그래서 위 경우 는 발전소를 하나만 세울 때라 고 볼 수 있다.

어느곳에 세우든 전체 필요한 전선의 길이는 같기 때문이다.

그래서 하나의 경우는 반환 값이 자명한 것이다.

 

그러나 발전소 개수가 2개 이상 정점의 개수 미만이면 얘기는 달라진다.

위 MST의 간선 중 발전소 개수를 뺀 개수의 간선 만 선택하고, 더욱이 이를 오름차순으로 선택하면 되는데,

오름차순으로 해야 필요한 전체 전선의 길이가 최소가 되고,

더욱이 원래 MST는 연결 그래프이고,

[A - B - C]  [D - E] 이런 식으로 선택되더라도, 발전소의 개수가 여러개이기 때문에 해당 그룹 내에서는 전기가 공급되기 때문에 논리적으로 연결그래프라 볼 수 있기 때문이다. 

 

 

 

'알고리즘 > SWEA' 카테고리의 다른 글

5658  (0) 2021.11.04
7673  (0) 2021.11.03
7730  (0) 2021.11.03
1953  (0) 2021.11.03
7396  (0) 2021.11.03