목차
- 개요
- 본문
- 1) 문제
- 2) 과정
- 3) 코드 전체
개요
이번에 알고리즘 스터디에서 JAVA를 이용해 백준 9470번 Strahler 순서를 풀었습니다. 이를 정리해보고자 합니다.
9470번: Strahler 순서
지질학에서 하천계는 유향그래프로 나타낼 수 있다. 강은 간선으로 나타내며, 물이 흐르는 방향이 간선의 방향이 된다. 노드는 호수나 샘처럼 강이 시작하는 곳, 강이 합쳐지거나 나누어지는 곳
www.acmicpc.net
본문
1) 문제
2) 과정
5시간에 걸쳐서 풀었던 위상정렬 문제입니다... 기본 위상정렬 문제에 strahler 순서에 따른 조건이 추가되어 문제를 이해하고 만드는데 어려움을 겪었던 문제였어요... "나머지 노드는 그 노드로 들어오는 강의 순서 중 가장 큰 값을 i라고 했을 때, ... " 부분의 조건을 제대로 안읽어서 한번 틀렸었고 그 후엔 바로 통과했습니다..
제가 문제를 풀며 사용했던 아이디어는 다음과 같습니다.
0. 테스트 케이스 수 만큼 1~n을 반복한다.
1. 노드들이 연결되는 노드들을 담고, 각 노드의 진입차수를 계산한다.
2. 큐에 진입차수가 0인 시작 노드들을 담고, 그들의 strahArr 수를 초기화해준다.
3. 큐를 돌기시작한다.
4. 큐에서 뽑은 수의 strahArr의 순서가 가장 큰 경우의 개수를 찾고 그 수가 2개이상이면 조건에 맞게 maxCnt를 증가시켜준다.
5. 그 후 가장 큰 maxCnt값을 업데이트한다.
6. 전위순회로 strahArr의 개수를 업데이트해나간다.
7. 모든 큐를 다 돌았다면 가장 큰 strahler 순서의 개수가 담긴 ans를 테스트케이스 번호와 함께 출력한다.
이번에 풀어본 문제들을 input, logic, output에 맞춰 나눠 보여드리고 빨리 마무리 짓겠습니다.. 설명은 주석으로 최대한 달아뒀어요!!
2-0) MyReader
// Inner Class - Read Input values
private static class MyReader{
BufferedReader br;
StringTokenizer st;
public MyReader(){ br = new BufferedReader(new InputStreamReader(System.in));}
public void readLine() throws IOException{ st = new StringTokenizer(br.readLine());}
public int nextInt(){ return Integer.parseInt(st.nextToken());}
}
BufferedReader와 StringTokenizer를 쓸때마다 Integer.parseInt(st.nextToken()) 이런식으로 긴 문장을 쓰는게 싫어서 클래스로 분리해 코드 길이를 줄여보았습니다. 아예 시작전에 이것부터 만들면서 머리도 풀고 손도 풀수있어 꽤 맘에 들던 루틴이었어요.
2-1) Input
public static void main(String[] args) throws IOException {
// Input
MyReader mr = new MyReader();
mr.readLine();
int t = mr.nextInt(); // number of tests for this program
// repeat for loop as many as testcase
for(int i=0;i<t;i++){
mr.readLine();
int tNum = mr.nextInt(); // testcase number
int nNum = mr.nextInt(); // node number
int eNum = mr.nextInt(); // edge number
// initialize connecting info and indegree value
ArrayList<Integer>[] orgArr = new ArrayList[nNum+1]; //[노드번호][노드가 연결하는 노드들]
for(int j=1;j<=nNum;j++) orgArr[j] = new ArrayList<>(); // 진출간선을 담음 + 초기화
int[] indegree = new int[nNum+1]; // 진입간선의 수를 담기 위함.
// connecting edges
for(int j=0;j<eNum;j++){
mr.readLine();
int a = mr.nextInt(); // start point
int b = mr.nextInt(); // end point
orgArr[a].add(b); // connecting (a->b)
indegree[b]++; // increase b's indegree value
}
}
}
2-2) Logic & Output
public static void main(String[] args) throws IOException {
// Logic
// initialize queue and strahler array
Queue<Integer> q = new ArrayDeque<>(); // 위상정렬을 할 때 수를 담을 큐
int[][] strahArr = new int[nNum + 1][nNum + 1]; // [노드번호][해당 strahler순서의 개수]
for(int j=1;j<=nNum;j++) {
// 진입차수가 0이라면 q와 strahArr에 해당 노드를 넣어줌.
if(indegree[j]==0){
q.add(j);
strahArr[j][1] = 1; // => j의 strahler순서가 1인 것의 개수는 1이다
}
}
// do topological sort
int ans = 0;
while(!q.isEmpty()){
// get a number
int cur = q.poll();
// find Max Strahler order count
int maxCnt = 0;
for(int loop=nNum-1;loop>=0;loop--){
if(strahArr[cur][loop]>0) {
maxCnt = loop;
break;
}
}
// strahler 순서가 cur인게 2개 이상이면 들어오는 strahler 순서 중 가장 큰값을 1증가시킨다.
if(strahArr[cur][maxCnt]>1) {
maxCnt++;
strahArr[cur][maxCnt] = 1;
}
// update max strahler order
ans = Math.max(maxCnt,ans);
// do preorder traversal
for(int next:orgArr[cur]) {
// increase next's strahler count
strahArr[next][maxCnt]++;
// cut the edge -> subtract the degree of entry
indegree[next]--;
// if indegree is 0, put it in the q
if(indegree[next]==0) q.add(next);
}
}
// Output
System.out.println(tNum+" "+ans);
}
}
3) 전체코드
그렇게 완성된 코드는 아래쪽에 링크된 깃헙 레포짓토리에 방문하여 확인해주세요!
앞서 말씀드렸듯이 소요시간, 아이디어, 에러로그 등 더 자세히 보실 수 있습니다.
https://github.com/Park1122/Algorithm-Study/blob/master/sujeong/topological_sort/BOJ9470.java
GitHub - Park1122/Algorithm-Study: 명지대학교 학생들이 모여서 만든 알고리즘 공부 및 코딩테스트 준비
명지대학교 학생들이 모여서 만든 알고리즘 공부 및 코딩테스트 준비를 위한 스터디입니다. Contribute to Park1122/Algorithm-Study development by creating an account on GitHub.
github.com
'알고리즘(JAVA 사용) > Topological Sort' 카테고리의 다른 글
[알고리즘풀이]백준 1516 : 게임 개발 JAVA (2) | 2022.02.03 |
---|---|
[알고리즘풀이]백준 2056 : 작업 JAVA (0) | 2022.02.03 |
[알고리즘풀이]백준 2623 : 음악프로그램 JAVA (0) | 2022.02.03 |
[알고리즘풀이]백준 2252 : 줄 세우기 JAVA (0) | 2022.02.03 |
[알고리즘풀이]백준 2637 : 장난감 조립 JAVA (0) | 2022.02.03 |