https://www.acmicpc.net/problem/4315
4315번: 나무 위의 구슬
입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 n이 주어지며, n은 정점의 개수이다. 다음 n개 줄에는 각 정점의 정보가 주어진다. 첫 번째 숫자는 정점의 번
www.acmicpc.net
문제를 요약하면 어떤 정점들에 여러 개의 구슬이 있을 때, 적당히 배분하여 모든 정점에 구슬이 딱 1개만 존재하도록 하는 것이다.
이 문제의 핵심은 바로 "리프 노드부터 구슬을 채워나간다"는 것이다.
따라서 dfs로 리프노드부터 탐색해 부모 노드와 현재 노드의 구슬의 차이만큼 구슬의 상태를 변화하고, 이 차이의 절댓값만큼 답을 더해주면 된다.
사실 코드는 굉장히 간단하지만 리프 노드부터 채워나간다는 생각을 하기 어려웠던 문제인 것 같다.
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
vector<vector<int>> v;
int n, ball[10001], parent[10001];
long long ans;
void go(int node)
{
for (auto &i : v[node])
{
go(i);
}
ball[parent[node]] += (ball[node] - 1);
ans += abs(ball[node] - 1);
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
while (cin >> n, n != 0)
{
v.clear();
v.resize(n + 1);
memset(ball, 0, sizeof(ball));
memset(parent, 0, sizeof(parent));
ans = 0;
for (int i = 1; i <= n; i++)
{
int a;
cin >> a;
cin >> ball[i];
cin >> a;
for (int j = 0; j < a; j++)
{
int b;
cin >> b;
parent[b] = i;
v[i].push_back(b);
}
}
for (int i = 1; i <= n; i++)
{
if (parent[i] == 0)
{
go(i);
}
}
cout << ans << '\n';
}
}
'ps' 카테고리의 다른 글
[백준] 2982 - 국왕의 방문 (0) | 2023.01.22 |
---|---|
[백준] 2307 - 도로검문 (0) | 2023.01.21 |
[백준] 17831 - 대기업 승범이네 (0) | 2023.01.16 |
[백준] 1749 - 점수따먹기 (0) | 2023.01.16 |
[백준] 20188 - 등산 마니아 (0) | 2023.01.12 |
댓글