728x90
반응형
1. 문제
https://www.acmicpc.net/problem/2533
2. 알고리즘 분류
- 다이나믹 프로그래밍
- 트리
- 트리에서의 다이나믹 프로그래밍
3. 소스 코드
#include <iostream>
#include <vector>
#include <algorithm>
#define MAX_N 1000006
using namespace std;
int N;
vector<int> graph[MAX_N];
int dp[MAX_N][2]; // dp[x][y] = x번 노드가 0(얼리 아답터) 또는 1(일반인) 경우,
bool visited[MAX_N];
void dfs(int cur)
{
visited[cur] = true;
dp[cur][0] = 1; // 얼리 아답터인 경우 1
// 1. 현재 노드가 0(얼리 아답터)인 경우, dp[현재 노드][얼리 아답터] += min(dp[다음 탐색 노드][얼리 아답터], dp[다음 탐색 노드][일반인])
// 2. 현재 노드가 1(일반인)인 경우, dp[현재 노드][일반인] += dp[다음 탐색 노드][얼리 아답터]
for (int i = 0; i < graph[cur].size(); i++) {
int next = graph[cur][i];
if (visited[next]) continue;
dfs(next);
dp[cur][1] += dp[next][0]; // 현재 노드가 1(일반인)인 경우, 다음 탐색 노드의 0(얼리 아답터)일 때의 값 더하기
dp[cur][0] += min(dp[next][1], dp[next][0]); // 현재 노드가 0(얼리 아답터)인 경우, min(다음 탐색 노드가 1(일반인)일 떄의 경우, 다음 탐색 노드가 0(얼리 아답터)인 경우) 더하기
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
// N : 정점 개수
cin >> N;
// 그래프 입력
for (int i = 0; i < N; i++) {
int u, v;
cin >> u >> v;
graph[u].push_back(v);
graph[v].push_back(u);
}
// 1번부터 탐색
dfs(1);
// 1번이 얼리 아답터인 경우와 일반인인 경우, 총 2개의 경우 중에서 작은 값 출력
cout << min(dp[1][0], dp[1][1]);
return 0;
}
4. 유용한 알고리즘
1) DFS(깊이 우선 탐색) 알고리즘
1. 정의
- 시작 노드에서 자식 노드들을 순서대로 탐색하면서 깊이를 우선 탐색
2. 활용
- 모든 노드 탐색할 때 사용하는 알고리즘
2) DP(다이나믹 프로그래밍)
1. 정의
- 점화식 풀이 과정 중 하나
- 초항에서 천천히 기록해나가면서 풀어나가는 방법
2. 활용
- 점화식 활용 문제
728x90
'백준 알고리즘 > 백준 CLASS 6' 카테고리의 다른 글
[백준 C++] 2042번: 구간 합 구하기 (0) | 2024.09.13 |
---|---|
[백준 C++] 16565번: N포커 (0) | 2024.09.05 |
[백준 C++] 15824번: 너 봄에는 캡사이신이 맛있단다 (2) | 2024.06.15 |
[백준 C++] 13334번: 철로 (0) | 2024.06.09 |
[백준 C++] 14725번: 개미굴 (0) | 2024.06.09 |