[SWEA] 1267 [S/W 문제해결 응용] 10일차 - 작업순서 (파이썬 python)

2022. 8. 12. 15:01· Algorithm/SWEA

 

 

문제 링크

 

 

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV18TrIqIwUCFAZN 

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

 

 

문제 풀이

 

위상정렬을 활용해서 문제를 풀이했다.

 

 

위상정렬이란?

 

- 순서가 정해져 있는 일련의 작업을 차례대로 수행해야 할 때 사용할 수 있는 알고리즘

- 사이클이 없는 방향 그래프의 모든 노드를 '방향성에 거스르지 않도록 순서대로 나열하는 것'

- 기본 조건으로 위상 정렬을 수행할 수 있는 그래프는 사이클이 없는 방향 그래프이다.

 

* 진입차수(Indegree) : 특정한 노드로 들어오는 간선의 개수

* 진출차수(Outdegree) : 특정한 노드에서 나가는 간선의 개수

 

 

알고리즘 동작 과정

 

1) 진입차수가 0인 노드를 큐에 넣는다

2) 큐가 빌 때까지 다음 과정을 반복한다

1. 큐에서 원소를 꺼내 해당 노드에서 나가는 간선을 그래프에서 제거

2. 새롭게 진입차수가 0이 된 노드를 큐에 삽입

 

 

위상 정렬 특징

 

1) 사이클이 없는 방향 그래프에서만 수행 가능

2) 위상 정렬에서는 여러 답이 존재할 수 있다

=> 하나의 노드에서 여러 개의 노드로 간선이 존재 한다면,

그 순서가 달라질 수 있기 때문

3) 모든 원소를 방문하기 전에 큐가 비게 된다면 사이클이 존재한다고 판단

4) 보통 큐로 구현하지만 DFS를 이용해서 풀 수도 있음

 

 

시간 복잡도

 

차례대로 모든 노드를 확인하면서 O(V)

해당 노드에서 출발하는 간선을 차례로 제거 O(E) 해야 함

=> O(V + E)

 

 

from collections import deque
for tc in range(1, 11):
    v, e = map(int, input().split())
    edges = list(map(int, input().split()))  # 간선

    indegree = [0] * (v + 1)   # 진입차수
    graph = [[] for _ in range(v + 1)]  # 연결된 노드

    queue = deque()
    result = []

    for i in range(0, e):
        start = edges[i * 2]
        end = edges[i * 2 + 1]
        graph[start].append(end)
        indegree[end] += 1

    for i in range(1, v + 1):
        if indegree[i] == 0:
            queue.append(i)

    while queue:
        now = queue.pop()
        result.append(now)
        for i in graph[now]:
            indegree[i] -= 1
            if indegree[i] == 0:
                queue.append(i)

    result = ' '.join(list(map(str, result)))
    print("#{} {}".format(tc, result))

 

 

노드에 대한 숫자는 1부터 시작하므로,

진입 차수와 연결된 노드를 저장하는 indegree, graph 리스트를

v + 1까지의 범위로 초기화했다.

 

입력받은 간선을 표현하는 정점들을 저장하기 위해 graph 리스트에

graph[0번 인덱스의 값] = 1번 인덱스의 값

의 형식으로 짝수번째 인덱스의 값의 노드에서

홀수번째 인덱스의 값의 노드로 이동함을 저장했다.

이와 함께 홀수번째 인덱스의 값에 대한 indegree, 즉 진입차수는 1씩 증가시켜주었다.

 

진입 차수가 0인 것들을 하나씩 지워내며,

그 노드와 연결된 노드들의 진입 차수 역시 1씩 줄어나가는 알고리즘을 구현하기 위해

 

먼저, 진입차수가 0인 노드들을 큐에 넣어주었다.

(진입 차수가 0이라는 것은 가장 먼저 출발하는 노드라는 뜻)

 

큐에 넣은 것들을 하나씩 빼주며 결과 리스트에 더해주고

해당 노드에서 이동하게 되는 노드를 graph 리스트에서 빼내어

연결된 노드의 진입차수 값을 1씩 빼준다.

 

(이 때 큐에서 pop()을 하는 방식에 따라 결과값이 달라질 수 있다.)

 

진입 차수가 0이 된 노드가 있다면 다시 큐에 넣어주고

큐에 값이 없을 때까지 이를 반복한다.

 

이 반복이 끝난 후에 결과 리스트에 저장된 값이

작업 순서가 된다.

저작자표시 비영리 변경금지 (새창열림)

'Algorithm > SWEA' 카테고리의 다른 글

[SWEA] 1219 [S/W 문제해결 응용] 4일차 - 길찾기 (파이썬 python)  (0) 2022.08.12
[SWEA] 1224 [S/W 문제해결 응용] 6일차 - 계산기3 (파이썬 python)  (0) 2022.08.12
[SWEA] 1234 [S/W 문제해결 응용] 10일차 - 비밀번호 (파이썬 python)  (0) 2022.08.12
'Algorithm/SWEA' 카테고리의 다른 글
  • [SWEA] 1219 [S/W 문제해결 응용] 4일차 - 길찾기 (파이썬 python)
  • [SWEA] 1224 [S/W 문제해결 응용] 6일차 - 계산기3 (파이썬 python)
  • [SWEA] 1234 [S/W 문제해결 응용] 10일차 - 비밀번호 (파이썬 python)
YOONJELLY
YOONJELLY
YOONJELLY
JELLYJELLY
YOONJELLY
전체
오늘
어제
  • 분류 전체보기 (153)
    • Springboot (2)
    • Android (15)
    • Algorithm (126)
      • 개념 (8)
      • BOJ (91)
      • Programmers (15)
      • SWEA (4)
    • 경험_기록 (1)
    • RIM_TIP (4)
    • Github (2)
    • CS (1)
      • 운영체제 (1)
      • 컴퓨터네트워크 (0)
      • 정보처리기사 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 자료구조
  • 백준
  • 정렬
  • 문자열
  • 코틀린
  • BOJ
  • Python
  • 소프티어
  • 안드로이드
  • 이진탐색
  • 딕셔너리
  • 파이썬
  • 완전탐색
  • Android
  • 프로그래머스
  • 액티비티컴포넌트
  • 코딩테스트
  • BFS
  • DFS
  • programmers
  • 알고리즘
  • 스택
  • kotlin
  • 그리디
  • 이것이코딩테스트다
  • SWEA
  • DP
  • softeer
  • 큐
  • 다이나믹프로그래밍

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
YOONJELLY
[SWEA] 1267 [S/W 문제해결 응용] 10일차 - 작업순서 (파이썬 python)
상단으로

티스토리툴바

단축키

내 블로그

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

블로그 게시글

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

모든 영역

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

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