일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- ProGuard
- Python
- 코루틴
- pandas
- Codeforces
- Hilt
- Coroutines
- textfield
- architecture
- MyVoca
- 코드포스
- 프로그래머스
- 쿠링
- android
- Rxjava
- 백준
- boj
- AWS
- Kotlin
- MiTweet
- relay
- activity
- TEST
- 암호학
- GitHub
- Gradle
- androidStudio
- livedata
- Compose
- Coroutine
- Today
- Total
이동식 저장소
17616. 등수 찾기 본문
어제 union find 공부한 게 기억에 남아서, 대충 비슷해 보이는 문제를 풀기로 했다.
17616번: 등수 찾기
표준 입력으로 다음 정보가 주어진다. 첫 번째 줄에 세 정수 N, M, X가 공백을 사이에 두고 주어진다. (2 ≤ N ≤ 105, 1 ≤ M ≤ min(N(N-1)/2, 5×105), 1 ≤ X ≤ N) . 다음 M 줄에는 각각 두 정수 A, B가 주어
www.acmicpc.net
두 학생의 상대적인 순위를 비교한 데이터가 주어질 때, 학생
어제 공부한 union find 업데이트를 적용해 보자. 등수가 가장 높은 학생을 루트로 하는 집합이 있을 때,
int find(int n)
{
if (root[n] == n)
return n;
auto parent = find(n);
above[n] += above[parent] + 1;
return root[n] = parent;
}
merge는 어떻게 짜지? 어제 문제에서 모든 간선의 길이가 1인 그래프라고 생각하면 되지 않을까?
void merge(int a, int b, int w)
{
int root1 = find(a), root2 = find(b);
if (root1 == root2)
return;
// merge?
above[root2] = above[a] + 1 - above[b];
root[root2] = root1;
}
흠.. 그런데 이렇게 하면
생각해 보니, 어제 문제와는 아주 큰 차이가 있다. 어제 문제에서는 무게의 차이까지 모두 주어졌기 때문에 무게 차이를 merge할 수 있었지만, 이 문제에서 주어지는 a b
쌍은 a
가 b
보다 정확히 몇 등이나 높은지 알려주지 않는다.
오히려 union find보다 위상 정렬을 써야 하지 않을까.
위상 정렬?
잘 생각해 보면,
그런데 위상 정렬은 한 방향으로밖에 정렬하지 못한다. 따라서
그럴거면 그냥 bfs 2번 하는 게 쉽지 않냐?
맞다
높은 순위에서 낮은 순위로 가는 간선과 낮은 순위에서 높은 순위로 가는 간선 두 개를 만들고, 각각 bfs하면 된다. 참 쉽죠? union find 없이도 풀 수 있다~

에잉.. union find는 따로 연습해야지..
'Problem Solving > BOJ' 카테고리의 다른 글
13141. Ignition (0) | 2022.08.18 |
---|---|
9938. 방 청소 (1) | 2022.08.16 |
3830. 교수님은 기다리지 않는다 (0) | 2022.08.14 |
1184. 귀농 (0) | 2022.07.31 |
14711. 타일 뒤집기 (Easy) (0) | 2022.07.25 |