b2623. 음악프로그램

2024. 12. 17. 16:44·Algorithm & Data Structures/BOJ

 

https://www.acmicpc.net/problem/2623

 

 

 

보조 PD들이 짜온 순서를 만족하는 경우의수가 있는지 확인하는 문제.

이 문제를 읽자마자 떠오른 아이디어로 위상정렬이 떠올랐다.

보조 PD들의 입력을 받고 이후 보조 PD들이 생각하는 순서에 맞추어 가수들의 가중치를

부여하였다.

 

singer ArrayList로 어떤 가수가 앞에 서야하는지 controll하였고

singerCount 로 현재 어떤 가수가 앞에 빠짐으로써 지금 순위가 어떻게 잡히는지 카운트 해주었다.

 

문제 풀이 자체는 쉬웠지만 위상정렬을 자주 쓰지 않다보니 구현하는 부분에서 쓸데없는

코드가 많아지는 기분이 들었다.

 

 

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

public class Main {

    static int N, M; // 가수 수 N , 보조 PD 수 M
    static ArrayList<Integer>[] singer;
    static boolean[] isVisited;

    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());
        singer = new ArrayList[N+1];
        isVisited = new boolean[N+1];

        for (int i = 0 ; i <= N ; i++)
            singer[i] = new ArrayList<>();

        for (int i = 0 ; i < M ; i++){
            String[] input = br.readLine().split(" ");
            int pdCount = Integer.parseInt(input[0]);

            for(int j = 1 ; j <= pdCount ; j++ ){
                int now  = Integer.parseInt(input[j]);
                for (int k = j+1 ; k <= pdCount; k++){
                    int target  = Integer.parseInt(input[k]);
                    if(!singer[target].contains(now)) singer[target].add(now);  // ?
                }
            }
        }
        int[] singerCount = new int[N+1];
        Arrays.fill(singerCount,0);
        for(int i = 1 ; i <= N; i++){
            int count = singer[i].size();
            singerCount[i] = count;
        }

        Queue<Integer> q = new ArrayDeque<>();

        for (int i = 1 ; i <= N ; i++)
            if(singerCount[i] == 0) {
                isVisited[i] = true;
                q.add(i);
            }

        if (q.isEmpty()) {
            System.out.println(0);
            return ;
        }

        int ansCount = 0;
        StringBuilder sb = new StringBuilder();
        while(!q.isEmpty()){
            int now = q.poll();
            ansCount ++;
            sb.append(now);
            sb.append('\n');
            for (int i = 1 ; i <= N ; i++) {
                if (i == now) continue;
                if (singer[i].contains(now))
                    singerCount[i]--;
                if (singerCount[i] == 0 && !isVisited[i]) {
                    isVisited[i] = true;
                    q.add(i);
                }
            }
        }
        if (ansCount == N)
            System.out.println(sb);
        else
            System.out.println(0);
    }
}

 

 

 

타인의 코드를 참고하여본 결과 나의 위상정렬 알고리즘에

여러가지 비효율적인 부분이 존재했다. 

 

간선 가중치 부여 부분에 있어서 

다른 보조 PD 가 123 으로 했다면 2번이 끝나기전엔 3번이 나올수 없기에

012 로 부여하기보다

011 로 부여하여도 문제가 없다는 부분이다.

 

1 번 2 번 3 번 4 번 5번 가수가 순서대로 나와야 하고

4 번 6번 가수가 순서대로 나와야한다고 2명의 보조 PD가 

주장하고 있을때

나는 가중치를 012341로 지정하고 있었고

 

백준의 의문의 고수께서는 011111 로 지정하고 있었기에

인접리스트로 간선 연결 확인과정에서 가중치를 제거해줄때 접근 횟수도 

적었다.

 

 

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

public class Main {

    static int N, M; // 가수 수 N , 보조 PD 수 M
    static ArrayList<Integer>[] singer; 
    static int[] inDegree; 

    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());
        singer = new ArrayList[N + 1];
        inDegree = new int[N + 1];

        for (int i = 0; i <= N; i++) 
            singer[i] = new ArrayList<>();

        for (int i = 0; i < M; i++) {
            st = new StringTokenizer(br.readLine());
            int pdCount = Integer.parseInt(st.nextToken());
            int prev = Integer.parseInt(st.nextToken()); 

            for (int j = 1; j < pdCount; j++) {
                int now = Integer.parseInt(st.nextToken()); 
                singer[prev].add(now);
                inDegree[now]++; 
                prev = now; 
            }
        }

        Queue<Integer> q = new ArrayDeque<>();
        for (int i = 1; i <= N; i++) {
            if (inDegree[i] == 0) q.add(i);
        }

        StringBuilder sb = new StringBuilder();
        int visitedCount = 0;

        while (!q.isEmpty()) {
            int now = q.poll();
            sb.append(now).append('\n');
            visitedCount++;

            for (int next : singer[now]) {
                inDegree[next]--; 
                if (inDegree[next] == 0) q.add(next); 
            }
        }

        if (visitedCount == N) System.out.print(sb);
        else System.out.println(0);
    }
}

 

'Algorithm & Data Structures > BOJ' 카테고리의 다른 글

b7579. 앱  (0) 2024.12.26
b7453. 합이 0인 네정수  (1) 2024.12.20
b1024. 수열의 합  (0) 2024.12.15
b.2473 세용액  (0) 2024.12.11
b.1562 계단수  (2) 2024.12.09
'Algorithm & Data Structures/BOJ' 카테고리의 다른 글
  • b7579. 앱
  • b7453. 합이 0인 네정수
  • b1024. 수열의 합
  • b.2473 세용액
Geisha
Geisha
개발 일기
  • Geisha
    Geisha
    Geisha
  • 전체
    오늘
    어제
    • 분류 전체보기 (304) N
      • Algorithm & Data Structures (230) N
        • BOJ (89) N
        • SWEA (1)
        • Programers (136)
        • Data Structures (3)
      • DB (21) N
        • SQL (15) N
        • RDBMS (2)
      • Java (1)
        • Class (1)
      • Spring (5)
        • Spring MVC (1)
        • Annotations (1)
      • CS (36)
        • 운영체제 (13)
        • 네트워크 (5)
      • Tool (6)
        • Git (5)
        • AWS (1)
      • Project (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    baekjoon
    BFS
    algorithm
    programmers
    후위순회
    binarySearch
    다익스트라
    Stack
    dp
    Union-Find
    백준
    동적계획법
    유니온파인드
    구현
    백트래킹
    dfs
    프로그래머스
    투포인터
    이진탐색
    전위순회
    unionfind
    이분탐색
    Dijkstra
    경로압축
    스택
    PriorityQueue
    Java
    위상정렬
    DynamicProgramming
    알고리즘
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
Geisha
b2623. 음악프로그램
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.