Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- BOJ1753
- BOJ11404
- boj
- 1520내리막길
- 재귀
- github_actions
- BOJ14719
- BOJ14501
- 백준
- BOJ2805
- DP
- BFS
- BOJ2629
- 백트래킹
- 색종이와가위
- 백준2110
- 이분탐색
- BOJ20444
- BOJ2110
- html
- 백준11404
- BOJ1931
- 프로그래머스 #무지의먹방라이브 #C++
- 백준 #BOJ #1697
- 생활코딩
- BOJ11729
- 백준2533
- BOJ11066
- BOJ9663
- 백준2141
Archives
- Today
- Total
poksul_log
# 2533. 사회망 서비스(SNS) 본문
관련 알고리즘 : 재귀, DP
문제 링크 : https://www.acmicpc.net/problem/2533
2533번: 사회망 서비스(SNS)
첫 번째 줄에는 친구 관계 트리의 정점 개수 N이 주어진다. 단, 2 ≤ N ≤ 1,000,000이며, 각 정점은 1부터 N까지 일련번호로 표현된다. 두 번째 줄부터 N-1개의 줄에는 각 줄마다 친구 관계 트리의 에
www.acmicpc.net
해결 과정
문제를 보면, 어떤 아이디어를 SNS에서 퍼뜨리고자 할 때
- 얼리 아답터가 아닌 사람은 모든 친구가 얼리 어답터여야 아이디어를 받아들임
- 얼리 어답터인 사람은 친구가 얼리 어답터인지 여부에 관계없이 아이디어를 받아들임
즉,
- 얼리 어답터가 X인 사람 => 연결된 친구들이 모두 얼리 어답터-----------
- 얼리 어답터가 O인 사람 => 연결된 친구가 얼리어답터 O/X 2경우로 나누어 계산, 더 작은 값
1번부터 차례로 돌며 깊이탐색 및 재귀 이용, 이후 메모이제이션을 통해 알맞은 값을 배열에 저장해준다.
- dp[i][0] += dp[i_child][1] // 부모 노드가 얼리아답터가 아닐 때, 자식 노드들은 모두 얼리어답터
- dp[i][1] = min (dp[i_child][0], dp[i_child][1]) // 부모 노드가 얼리아답터일때, 자식 노드들이 얼리어답터 O/X인 경우 중 최솟값
C++ 코드
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
vector<int> vec[1000001];
int dp[1000001][2]; // 얼리어답터 0, 얼리어답터x 1
bool check[1000001]; // 지난 곳 체크
void solve(int a) // 깊이탐색 & dp 이용
{
check[a] = true;
dp[a][1] = 1; // 얼리어답터라 가정 시, 결과값 본인 포함 1로 시작
for (int i = 0; i < vec[a].size(); i++)
{
int child = vec[a][i];
if (check[child] == false)
{
solve(child);
dp[a][0] += dp[child][1]; // 부모노드가 얼리어답터x일 때, 자식노드는 모두 얼리어답터
dp[a][1] += min(dp[child][1], dp[child][0]); // 부모노드가 얼리어답터일때, 자식노드 2가지 경우 중 최솟값
}
}
}
int main(void)
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
memset(check, false, sizeof(check)); // false로 초기화
int N; // 트리 정점 개수
cin >> N;
for (int i = 0; i < N-1; i++)
{
int u, v;
cin >> u >> v;
vec[u].push_back(v);
vec[v].push_back(u);
}
solve(1); // 첫번째 노드부터 돌며 dp
cout << min(dp[1][0], dp[1][1]); // 첫번째 노드가 얼리어답터일때와 아닐 때 중 최솟값 도출
}
'Coding Test > BOJ' 카테고리의 다른 글
# 11265. 끝나지 않는 파티 (0) | 2022.10.09 |
---|---|
# 1062. 가르침 (0) | 2022.10.02 |
# 1461. 도서관 (0) | 2022.09.12 |
# 2629. 양팔저울 (0) | 2022.08.28 |
# 20444. 색종이와 가위 (0) | 2022.08.14 |