일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Programmers
- 2294
- baekjoon
- NRVO
- UE5
- RVO
- 팰린드롬 만들기
- C++
- 오블완
- DeferredRendering
- 프로그래머스
- UnrealEngine5
- 1563
- DirectX11
- winapi
- directx
- 백준
- GeeksForGeeks
- Unreal Engine5
- softeer
- 티스토리챌린지
- 줄 세우기
- Frustum
- algorithm
- UnrealEngine4
- IFileDialog
- RootMotion
- const
- C
- 언리얼엔진5
- Today
- Total
Game Develop
[Algorithm] Programmers :: 등대 본문
https://school.programmers.co.kr/learn/courses/30/lessons/133500
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
vector<vector<int>> graph(100001);
bool visited[100001] = { false };
int answer = 0;
int DFS(int vertexNum)
{
if (graph[vertexNum].size()-1 == 0)
{
return 0;
}
int count = 0;
for (int i = 0; i < graph[vertexNum].size(); ++i)
{
int childVertex = graph[vertexNum][i];
if (visited[childVertex] == false)
{
visited[childVertex] = true;
count += DFS(childVertex);
}
}
if (count == graph[vertexNum].size()-1) return 0;
++answer;
return 1;
}
int solution(int n, vector<vector<int>> lighthouse)
{
for (int i = 0; i < lighthouse.size(); ++i)
{
int a = lighthouse[i][0];
int b = lighthouse[i][1];
graph[a].push_back(b);
graph[b].push_back(a);
}
visited[1] = true;
int count = 0;
for (int i = 0; i < graph[1].size(); ++i)
{
int childVertex = graph[1][i];
if (visited[childVertex] == false)
{
visited[childVertex] = true;
count += DFS(childVertex);
}
}
if (count < graph[1].size()) ++answer;
return answer;
}
|
cs |
문제 제대로 안읽고 순환그래프인줄 착각해서 헛고민에 상당히 빠졌던 문제.
문제에서 간선의 개수는 노드개수-1개, 즉 트리형태라고 설명이 되어있다.
결론만 말하자면, 자식노드가 하나라도 0이라면 반드시 자신(부모)는 등대를 켜야한다(1).
그렇다면 노드가 0이될 조건은 무엇인가... 가 다음 문제이다.
노드가 0이될 조건은 리프노드일 경우이다. 즉, 자식노드가 1개도 없을 때이다.
왜? 자식노드가 없기때문에 등대를 키는게 전혀 이득이 되지를 않는다.
최소의 등대를 키려면 하나의 등대를 켰을 때 최대한 많이 다른 등대를 안키게 만드는게 중요한데, 리프노드에서 등대를 켜봤자 잘해야 부모노드만 안켜도되는 이득이 있을 뿐이다.
근데 부모는 키는게 이득인 경우가 많다. 여러 자식을 거느린 부모의 경우, 부모가 킴으로써 자식은 안켜도 되는 상황이 있기 때문이다.
하지만 리프노드는 그런경우가 없으니 무조건 안키는게 좋다.
딱 위의 전제에서 문제해결이 시작된다.
자식노드가 하나라도 0이라면(리프노드같은) 반드시 자신은(부모는) 켜야한다.
왜? 문제조건(양 끝 노드중 한개는 반드시 켜야한다) 은 충족시켜야하니까.
그래서 리프노드같이 안켰을때는 부모에게 0을 리턴하고, 자식노드중 하나라도 0이여서 켰다면 부모에게 1을 리턴하는 식으로 작성했다. 그리고 누적값이 해당 노드랑 연결된 노드들의 개수 -1개와 누적값이 같다면 (즉, 자식들이 모두 켰다면) 부모에게 0을 리턴했다(자식들이 모두 켰으니 굳이 자기는 킬필요가 없다).
'Algorithm > Programmers' 카테고리의 다른 글
[Algorithm] Programmers :: 억억단을 외우자 (0) | 2023.09.03 |
---|---|
[Algorithm] Programmers :: 숫자 타자 대회 (0) | 2023.09.02 |
[Algorithm] Programmers :: 부대복귀 (0) | 2023.08.28 |
[Algorithm] Programmers :: 2차원 동전 뒤집기 (0) | 2023.08.28 |
[Algorithm] Programmers :: 고고학 최고의 발견 (0) | 2023.08.24 |