기록하지 않았다면 잃어버릴 시간들
Home
  • 분류 전체보기 (184)
    • Lang (6)
      • c++ (2)
      • Java (2)
      • python (2)
    • 프레임워크 (18)
      • Spring (16)
      • JPA (2)
    • 알고리즘 (141)
      • 이론 (4)
      • 백준 (59)
      • Codility (13)
      • 프로그래머스 (65)
    • CS (4)
      • 운영체제 (0)
      • 자료구조 (0)
      • DB (4)
      • 네트워크 (0)
      • 보안 (0)
    • 기타 (7)
    • 프로젝트 (4)
      • 게시판 만들기로 배우는 Spring Data JP.. (4)
Home
  • 분류 전체보기 (184)
    • Lang (6)
      • c++ (2)
      • Java (2)
      • python (2)
    • 프레임워크 (18)
      • Spring (16)
      • JPA (2)
    • 알고리즘 (141)
      • 이론 (4)
      • 백준 (59)
      • Codility (13)
      • 프로그래머스 (65)
    • CS (4)
      • 운영체제 (0)
      • 자료구조 (0)
      • DB (4)
      • 네트워크 (0)
      • 보안 (0)
    • 기타 (7)
    • 프로젝트 (4)
      • 게시판 만들기로 배우는 Spring Data JP.. (4)
블로그 내 검색

기록하지 않았다면 잃어버릴 시간들

새로운 것을 배우는게 즐거운 개발자입니다.

  • 알고리즘/백준

    BOJ2623/ C++

    2022. 1. 10.

    by. 내이름은 킹햄찌

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

     

    2623번: 음악프로그램

    첫째 줄에는 가수의 수 N과 보조 PD의 수 M이 주어진다. 가수는 번호 1, 2,…,N 으로 표시한다. 둘째 줄부터 각 보조 PD가 정한 순서들이 한 줄에 하나씩 나온다. 각 줄의 맨 앞에는 보조 PD가 담당한

    www.acmicpc.net

    백준 온라인저지 2623번 문제입니다. 

    위상정렬을 이용해서 풀었습니다.

     

    #include<iostream>
    #include<queue>
    #include<vector>
    #define MAX 1001
    using namespace std;
    
    int indegree[MAX];
    vector<int> adj[MAX];
    vector<int> ans;
    
    int n, m;
    
    void Input() {
    	cin >> n >> m;
    	for (int i = 0; i < m; i++) {
    		int cnt;
    		int previous = 0;
    		int input = 0;
    		cin >> cnt >> previous;
    		
    		while(--cnt){
    			cin >> input;
    			adj[previous].push_back(input);
    			indegree[input]++;
    			previous = input;
    		}
    	}
    }
    
    void solution() {
    	queue<int>q;
    	for (int i = 1; i <= n; i++) 
    		if (!indegree[i])
    			q.push(i);
    
    	while (!q.empty()) {
    		int current = q.front();
    		q.pop();
    		ans.push_back(current);
    		
    		for (auto iter : adj[current]) {
    			int next = iter;
    			if (--indegree[next] == 0)
    				q.push(next);
    		}
    	}
    
    	if (ans.size() != n) {
    		ans.clear();
    		ans.push_back(0);
    	}
    	for (auto iter : ans)
    		cout << iter << "\n";
    }
    
    
    int main(void) {
    	Input();
    	solution();
    }
    /*
    반례 1   
    q가 비었는지만 확인하면 1 2만 확인하여 단방향 그래프로 판단해버림
    4 3
    2 1 2
    2 3 4
    2 4 3
    
    반례 2
    중복입력의 케이스
    3 2
    2 2 3
    3 2 3 1
    */

    아이디어

    이 문제에서 주의할 점은 중복간선이 들어왔을때에 대한 처리와 양방향 그래프가 되어 위상정렬을 적용할 수 없는 케이스를 찾아내는 것이라 생각했음

    처음에는 입력 받는부분에서 중복데이터가 들어왔을때 처리를 bool check[MAX][MAX]를 이용한 dp방식으로 하였고, 양방향 그래프에 대한 처리는 진입차수가 없는 노드들만 q에 넣는 방식으로 처리했었는데 아래의 반례에 모두 꺠졌음

    두가지 모두 만족 시킬수 있는 방법은 위상정렬을 이용해 정렬된 숫자들을 ans에 넣고 출력해야하는 개수와 ans에 있는 개수가 같은지 (ans.size() != n) 체크만 하면 됨 

     

    엄청박살났지만 포기안함

    '알고리즘 > 백준' 카테고리의 다른 글

    BOJ9470/ C++  (0) 2022.01.26
    BOJ11651/ C++  (0) 2022.01.26
    BOJ2637/ C++  (0) 2022.01.10
    BOJ2637/ C++  (0) 2022.01.03
    BOJ1516/ C++  (0) 2022.01.03

    댓글

    관련글

    • BOJ9470/ C++ 2022.01.26
    • BOJ11651/ C++ 2022.01.26
    • BOJ2637/ C++ 2022.01.10
    • BOJ2637/ C++ 2022.01.03
    맨 위로
전체 글 보기
Tistory 로그인
Tistory 로그아웃
로그아웃 글쓰기 관리

Today

Total

Powered by ⓒ Kakao Corp.

Designed by Nana
블로그 이미지
내이름은 킹햄찌

티스토리툴바