발자취
[프로그래머스 Lv.2 / C++] Day76. 전력망을 둘로 나누기 본문
2024. 08. 18 - 코딩테스트 스터디 Day76
01. 문제 설명
n개의 송전탑이 전선을 통해 하나의 트리 형태로 연결되어 있습니다. 당신은 이 전선들 중 하나를 끊어서 현재의 전력망 네트워크를 2개로 분할하려고 합니다. 이때, 두 전력망이 갖게 되는 송전탑의 개수를 최대한 비슷하게 맞추고자 합니다.
송전탑의 개수 n, 그리고 전선 정보 wires가 매개변수로 주어집니다. 전선들 중 하나를 끊어서 송전탑 개수가 가능한 비슷하도록 두 전력망으로 나누었을 때, 두 전력망이 가지고 있는 송전탑 개수의 차이(절댓값)를 return 하도록 solution 함수를 완성해 주세요.
02. 제한사항
- n은 2 이상 100 이하인 자연수입니다.
- wires는 길이가 n-1인 정수형 2차원 배열입니다.
- wires의 각 원소는 [v1, v2] 2개의 자연수로 이루어져 있으며, 이는 전력망의 v1번 송전탑과 v2번 송전탑이 전선으로 연결되어 있다는 것을 의미합니다.
- 1 ≤ v1 < v2 ≤ n입니다.
- 전력망 네트워크가 하나의 트리 형태가 아닌 경우는 입력으로 주어지지 않습니다.
03. 입출력 예
| n | wires | result |
| 9 | [[1,3],[2,3],[3,4],[4,5],[4,6],[4,7],[7,8],[7,9]] | 3 |
| 4 | [[1,2],[2,3],[3,4]] | 0 |
| 7 | [[1,2],[2,7],[3,7],[3,4],[4,5],[6,7]] | 1 |
입출력 예 설명
입출력 예 #1
- 다음 그림은 주어진 입력을 해결하는 방법 중 하나를 나타낸 것입니다.
-

- 4번과 7번을 연결하는 전선을 끊으면 두 전력망은 각 6개와 3개의 송전탑을 가지며, 이보다 더 비슷한 개수로 전력망을 나눌 수 없습니다.
- 또 다른 방법으로는 3번과 4번을 연결하는 전선을 끊어도 최선의 정답을 도출할 수 있습니다.
입출력 예 #2
- 다음 그림은 주어진 입력을 해결하는 방법을 나타낸 것입니다.
-

- 2번과 3번을 연결하는 전선을 끊으면 두 전력망이 모두 2개의 송전탑을 가지게 되며, 이 방법이 최선입니다.
입출력 예 #3
- 다음 그림은 주어진 입력을 해결하는 방법을 나타낸 것입니다.
-

- 3번과 7번을 연결하는 전선을 끊으면 두 전력망이 각각 4개와 3개의 송전탑을 가지게 되며, 이 방법이 최선입니다.
4. 풀이 및 답
#include <string>
#include <vector>
#include <cmath>
#include <queue>
#define MAX 101
using namespace std;
int count;
vector<int> connect[101];
void bfs(int v1, int v2) {
queue<int> q;
vector<int> visit(MAX);
q.push(v1);
visit[v1] = 1;
visit[v2] = 1;
while (!q.empty()) {
int node = q.front();
q.pop();
for (int i = 0; i < connect[node].size(); i++) {
int node2 = connect[node][i];
if (visit[node2]) continue;
count++;
q.push(node2);
visit[node2] = 1;
}
}
}
int solution(int n, vector<vector<int>> wires) {
int answer = MAX;
for (auto x : wires) {
connect[x[0]].push_back(x[1]);
connect[x[1]].push_back(x[0]);
}
for (auto x : wires) {
count = 1;
int v1 = x[0];
int v2 = x[1];
bfs(v1, v2);
answer = min(answer, abs(2 * count - n));
}
return answer;
}BFS 탐색 시 서브 트리의 노드 개수를 저장하는 count 변수와 각 송전탑에 연결된 다른 송전탑의 번호를 저장하는 connect 벡터를 선언했다.
main
우선 wires 배열 속 정보를 통해 각 송전탑의 연결 관계를 connect에 저장한다.
예를 들어, wires 벡터에 [1,3]과 같은 요소가 존재한다면 connect[1]에 3을, connect[3]에 1을 push 한다.
그 뒤, 모든 전선을 한 번씩 끊어보면서 해당 전선으로 이루어진 두 송전탑을 각각 v1, v2로 두고 bfs 함수를 사용하여 각 두 전력망의 송전탑 개수의 차이를 계산한다. 이렇게 계산된 두 전력망의 송전탑 개수의 차이 중 최소를 찾아 갱신해 나간다.
bfs
q에 시작 노드를 넣고, 두 노드의 방문 여부를 표시하는 visit 배열의 값을 1로 바꾼다.
(v1은 시작 노드이므로 제외, v2는 방문하면 안 되기 때문에 제외하는 것이다.)
그 뒤, v1과 연결된 노드 중 아직 방문하지 않은 노드가 있다면 count를 증가시키고, q에 push 한 뒤 방문 처리를 하면서 송전탑 개수를 찾는다.

정답!

오늘 문제는 너무 어려워서 다른 분들의 풀이를 보고 이해하는 방식으로 풀어봤다
DFS, BFS는 너무 어려운 것 같다 허허
참고한 게시글
[프로그래머스] 전력망을 둘로 나누기 C++ (Lv.2)
https://school.programmers.co.kr/learn/courses/30/lessons/86971 프로그래머스 코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는
cherishvert.tistory.com
'코딩테스트 > Daily Coding (C, C++)' 카테고리의 다른 글
| [프로그래머스 Lv.2 / C++] Day78. 타겟 넘버 (0) | 2024.08.20 |
|---|---|
| [프로그래머스 Lv.2 / C++] Day77. 모음사전 (0) | 2024.08.19 |
| [프로그래머스 Lv.2 / C++] Day75. 피로도 (0) | 2024.08.17 |
| [프로그래머스 Lv.2 / C++] Day74. 카펫 (0) | 2024.08.16 |
| [프로그래머스 Lv.2 / C++] Day73. 소수 찾기 (0) | 2024.08.15 |