알고리즘
백준 9470번 Strahler 순서 (JAVA)
박카스마시며코딩
2022. 1. 17. 17:54
https://www.acmicpc.net/problem/9470
9470번: Strahler 순서
지질학에서 하천계는 유향그래프로 나타낼 수 있다. 강은 간선으로 나타내며, 물이 흐르는 방향이 간선의 방향이 된다. 노드는 호수나 샘처럼 강이 시작하는 곳, 강이 합쳐지거나 나누어지는 곳
www.acmicpc.net
저는 해당 문제를 위상정렬을 응용하여 문제를 해결하였습니다.
count배열를 통해 해당 노드를 Queue에 넣을라면 몇번 방문해야하는지를 체크했습니다.
number배열을 통해 해당 노드에 가장 큰 Strahler을 저장하였습니다.
isNumber는 해당 number배열에 있는 값이 한번 들어왔는지 두번 들어왔는지를 체크하였습니다.
이를 통해 Queue에 넣을 때 isNumber가 true거나 number값과 현재 노드의 Strahler를 비교하여 같다면 1 증가한 값을 다르다면 둘 중 큰 값을 넣었습니다
저는 처음에 isNumber를 사용하지 않아서 100%에서 틀렸습니다.
isNumber를 통해 이전에 해당 number에 해당하는 값이 두번이상 들어왔는지를 체크하였습니다.
package BOJ.ETC;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.StringTokenizer;
import java.util.function.Function;
public class BOJ_9470 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
Function<String, Integer> stoi = Integer::parseInt;
int test = stoi.apply(st.nextToken());
for (int t = 1; t <= test; t++) {
st = new StringTokenizer(br.readLine());
int k = stoi.apply(st.nextToken());
int n = stoi.apply(st.nextToken());
int m = stoi.apply(st.nextToken());
List<Integer>[] map = new ArrayList[n + 1];
int[] count = new int[n + 1];
for (int i = 0; i <= n; i++) {
map[i] = new ArrayList<>();
}
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int a = stoi.apply(st.nextToken());
int b = stoi.apply(st.nextToken());
map[a].add(b);
count[b]++;
}
System.out.printf("%d %d\n", k, bfs(map, count, n));
}
}
private static class Node{
int location;
int number;
public Node(int location, int number) {
this.location = location;
this.number = number;
}
}
private static int bfs(List<Integer>[] map, int[] count, int n) {
int[] number = new int[n+1];
boolean[] isNumber = new boolean[n+1];
Queue<Node> q = new LinkedList<>();
int result = 1;
for (int i = 1; i <= n; i++) {
if (count[i] == 0) {
q.offer(new Node(i,1));
}
}
while (!q.isEmpty()) {
Node now = q.poll();
// System.out.println(now.location+" "+now.number);
// System.out.println(Arrays.toString(number));
// System.out.println(Arrays.toString(count));
for (int i = 0; i < map[now.location].size(); i++) {
int next = map[now.location].get(i);
if (--count[next] == 0) {
if(number[next] == now.number || isNumber[next]){
q.offer(new Node(next,number[next]+1));
result = Math.max(number[next]+1,result);
}else{
q.offer(new Node(next,Math.max(now.number,number[next])));
}
}else{
if(number[next] == now.number){
isNumber[next] = true;
}else{
isNumber[next] = false;
number[next] = Math.max(now.number,number[next]);
}
}
}
}
return result;
}
}