[분류]

  • 탐색

[문제링크]

[요구사항]

  • 학생X의 순위 범위를 구한다.

[풀이]

  1. 아랫쪽에서 몇 등 할 수 있는지와 윗 쪽에서 몇 등을 할 수 있는지 각각 구하기 위해 단방향 그래프 두개를 생성한다.

  2. 두 개의 그래프에 대해서 각각 bfs 탐색을 수행하여 학생 X의 위에 최소 몇 개, 아래에 최소 몇 개인지 구한다.

  3. 최대 등수와 최소 등수를 구해서 출력한다.

[코드]

//baekjoon_17616_등수찾기


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.*;

public class Main {
    static int n, m, x;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());

        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        x = Integer.parseInt(st.nextToken());
        ListGraph up_graph = new ListGraph(n);
        ListGraph bottom_graph = new ListGraph(n);

        for(int i=0;i<m;i++){
            st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());
            bottom_graph.addList(x, y);
            up_graph.addList(y, x);
        }

        int up = getValue(up_graph) + 1;
        int bottom = n - getValue(bottom_graph);
        System.out.println(up + " " + bottom);
    }

    static private int getValue(ListGraph graph){
        int value = 0;
        boolean visited[] = new boolean[n+1];
        Queue<Integer> q = new LinkedList<>();
        q.add(x);
        visited[x] = true;

        while(!q.isEmpty()){
            int p = q.poll();
            ArrayList<Integer> list = graph.get(p);

            for(int i=0;i<list.size();i++){
                int idx = list.get(i);
                if(!visited[idx]){
                    visited[idx]=true;
                    q.add(idx);
                    value++;
                }
            }
        }
        return value;
    }
}

class ListGraph{
    private ArrayList<ArrayList<Integer>> listGraph;

    public ListGraph(int initSize){
        this.listGraph = new ArrayList<ArrayList<Integer>>();

        for(int i=0;i<initSize+1;i++){
            listGraph.add(new ArrayList<Integer>());
        }
    }

    public void addList(int x, int y){
        listGraph.get(x).add(y);
    }

    public ArrayList<Integer> get(int p) {
        return listGraph.get(p);
    }
}



[통과여부]

image

[느낀점]

처음에는 하나의 그래프로만 할려고 하다보니 코드가 복잡해지고 계속 틀려서 두 개를 만들자는 생각이 들었다. 역시 알고리즘은 생각의 전환이 좀 필요한 것 같다.