www.acmicpc.net/problem/1931

 

1931번: 회의실 배정

(1,4), (5,7), (8,11), (12,14) 를 이용할 수 있다.

www.acmicpc.net


문제설명

1. n개의 회의 스케줄이 주어진다.

2. 각 스케줄에는 (시작시간, 종료시간)이 주어진다.

3. 가장 많은 회의를 진행했을 때 개수는?

4. 단, 회의 시간이 종료되자마자 회의가 시작될 수 있으며, 회의시작 시간과 종료시간이 같을 수 있다.

 

문제 특징

- 회의가 빨리 끝나면 더 많은 회의를 할 수 있다.

하지만 단순히 회의 종료시간을 기준으로 오름차순을 하게 되면 반례에 걸리게 된다.

예를 들어, [5, 5], [5, 5], [4, 5]가 스케줄로 주어진다고 하자.

 

그렇다면 우리가 예상하는 답은 [4, 5], [5, 5], [5, 5]이다.

하지만 만약 회의 시작시간이 내림차순으로 되어 있다면 [5, 5], [5, 5], [4, 5]가 출력이 된다.

따라서 "종료시간(오름차순) -> 시작시간(오름차순)"으로 정렬이 이뤄져야 한다.

 

코드

import sys
import heapq
# sys.stdin = open("C:/Users/JIn/PycharmProjects/coding_Test/input.txt", "rt")

n = int(input())
heap = []
for _ in range(n):
    s, e = map(int, input().split())
    heapq.heappush(heap, (e, s))

cnt = 0
before_e = 0
while heap:
    e, s = heapq.heappop(heap)
    if s >= before_e:
        before_e = e
        cnt += 1
print(cnt)

 

 

7569번: 토마토

첫 줄에는 상자의 크기를 나타내는 두 정수 M,N과 쌓아올려지는 상자의 수를 나타내는 H가 주어진다. M은 상자의 가로 칸의 수, N은 상자의 세로 칸의 수를 나타낸다. 단, 2 ≤ M ≤ 100, 2 ≤ N ≤ 100,

www.acmicpc.net

 


문제

1. x, y, z 방향으로 BFS를 실행하는 문제다.

2. x, y는 격자무늬 상자 안에 있는 토마토의 좌표를 의미하며, z는 겹쳐 올린 상자의 층을 뜻한다.

3. 상자 안에 있는 토마토는 0, 1, -1의 상태를 가진다. 

(0 : 토마토가 익지 않았다,  1 : 토마토가 익었다,  -1 : 토마토가 존재하지 않는다)

4. 토마토는 매일 "상/하/좌/우/위/아래" 방향으로 전염되어 익는다.

5. 토마토가 익는 데 걸리는 최소 일 수을 출력한다. 

 - 처음부터 모든 토마토가 익었으면 0을 출력한다. 

 - 모든 토마토를 익히지 못한다면 -1을 출력한다. 

알고리즘

1. 3차원 배열에서의 BFS만 구현하면 된다. (기본 2차원 배열에서 배열을 하나 더 추가한 것이다.)

1. 익은 토마토의 좌표를 리스트에 담는다.

2. 익은 토마토를 중심으로 상/하/좌/우/위/아래로 좌표를 이동시킨다.

3. 이동한 좌표가 좌표평면에서 벗어나지 않는다면 계속 진행한다.

4. 이동 전 익은 토마토의 좌표의 값에 1을 더하여 이동 후의 좌표 평면에 1을 더해준다. (매일 주변에 있는 토마토가 익으므로, 좌표평면에 존재하는 값은 "지난 일수"를 의미 한다.)

5. 좌표를 이동함으로써 익게 된 토마토의 좌표를 리스트에 담는다.

 

6. x, y, z 방향으로 3중 반복문을 실행하여 토마토가 전부 익었는지 확인한다.

 - 모두 익지 않았다면 -1을 출력하고 프로그램을 종료한다. 

7. 최대 값(mx)을 1로 초기화한다.

 - 문제 조건에서 처음부터 토마토가 모두 익었으면 0을 출력하라고 했다.

8. x, y, z 방향으로 3중 반복문을 실행하여, mx와 비교하며 좌표 평면에서 가장 큰 수(익는데 걸린 일수)를 찾는다.

9. mx - 1을 해서 정답을 출력한다.

  - 시작 시에 좌표평면의 값이 1이므로, 익는데 걸린 시간에 포함시키지 않는다.

 

코드

import sys
from collections import deque
# sys.stdin = open("C:/Users/JIn/PycharmProjects/coding_Test/input.txt", "rt")


def BFS():
    while queue:
        x, y, z = queue.popleft()
        for dx, dy, dz in mv:
            xx = x + dx
            yy = y + dy
            zz = z + dz
            if 0 <= xx < col and 0 <= yy < row and 0 <= zz < height and board[zz][yy][xx] == 0:
                board[zz][yy][xx] = board[z][y][x] + 1
                queue.append([xx, yy, zz])

if __name__ == '__main__':
    col, row, height = map(int, input().split())
    board = [[list(map(int, input().split())) for _ in range(row)] for _ in range(height)]
    mv = ((1, 0, 0), (-1, 0, 0), (0, 1, 0), (0, -1, 0), (0, 0, 1), (0, 0, -1))

    # 익은 것의 좌표를 찾는다.
    queue = deque()
    for y in range(row):
        for x in range(col):
            for z in range(height):
                if board[z][y][x] == 1:
                    queue.append([x, y, z])

    BFS()
    # 모두 다 익었는지 확인한다.
    for y in range(row):
        for x in range(col):
            for z in range(height):
                if board[z][y][x] == 0:
                    print(-1)
                    sys.exit()

    # 걸린 일수를 출력한다.
    mx = 1
    for z in range(height):
        for y in range(row):
            mx = max(mx, max(board[z][y]))
    print(mx-1)
 

2839번: 설탕 배달

상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그

www.acmicpc.net


문제설명

1. 설탕을 담을 수 있는 3kg짜리 봉투와  5kg짜리 봉투가 있다.

2. 설탕의 무게인 N이 주어졌을 때 사용할 최소의 봉투를 출력하자.

3. 정답이 없다면, -1을 출력한다.

문제 특이사항

- 반례로 N이 11인 상황을 예로 들 수 있습니다.

일반적인 풀이로는 5kg짜리 봉투가 가장 많을 때 답이 된다고 생각할 수 있습니다.

이런 경우에는 5kg짜리 봉투를 2개를 사용한 뒤에 나머지를 3kg짜리 봉투에 담아야 합니다.

그렇게 되면 3kg짜리 봉투에 들어갈 수 있는 설탕의 양은 2kg 밖에 되지 않습니다. 

즉, 문제에서 요구하는 답을 낼 수 없습니다.

 

5kg짜리 봉투 1개에만 적당히 소금을 담고,  3kg짜리 봉투를 2개를 사용하여 설탕을 담으면 문제에서 요구하는 정답을 제출할 수 있습니다.

알고리즘

N이 11로 주어진 상황을 가정하고 설명하겠습니다.

1. 5kg짜리 봉투가 허용하는 최대 무게부터 5 단위로 감소시키며, 0까지 반복문을 실행합니다.

 

2. N에서 5가 허용하는 무게(10, 5, 0)를 뺍니다.

뺀 값은 다시 N에 담습니다.

 

3. N을 3으로 나눕니다. 이 때 나머지가 0이면, 반복문을 빠져나옵니다.

 

4. 답으로는 5의 "'배수(2)'가 되는 값 + N/3의 몫"으로 제출합니다. (나머지가 0인 것이 없다면 -1을 답으로 제출합니다)

 

 

 

 

 

코드

import sys
# sys.stdin = open("C:/Users/JIn/PycharmProjects/coding_Test/input.txt", "rt")

inputData = int(input())
T = inputData//5
answer = -1
for i in range(T, -1, -1):
    n = inputData - (5 * i)
    a, b = divmod(n, 3)
    if b == 0:
        answer = i + a
        break
print(answer)

 

 

코딩테스트 연습 - 구명보트

무인도에 갇힌 사람들을 구명보트를 이용하여 구출하려고 합니다. 구명보트는 작아서 한 번에 최대 2명씩 밖에 탈 수 없고, 무게 제한도 있습니다. 예를 들어, 사람들의 몸무게가 [70kg, 50kg, 80kg, 5

programmers.co.kr


문제

1. 구명보트에 탈 사람들의 몸무게가 리스트(people)로 주어진다. 

2. 구명보트는 최대 2명이 탑승할 수 있다. (단, 구명보트의 최대 탑승 무게(limit) 보다 적어야 한다.)

3. 모든 사람들이 구명보트를 통해 탈출해야 한다.

4. 항상 사람의 무게는 구명보트의 최대 무게보다 작다.

 

문제 특징

1. 효율성 테스트가 상당히 엄격했다. 반드시 1개의 반복문을 통해서만 코드를 작성해야 한다.

2. people이 [30, 40, 60, 70]인 반례 상황이 존재한다. 

[30+40, 60, 70]으로 배를 탈 수도 있지만, [30+70, 40+60]으로 배를 탈 수도 있다. 후자가 문제에서 요구하는 정답이다.

 

알고리즘

- people을 정렬시킨다. 

- 리스트(people)의 맨 앞에서 뒤쪽으로 이동하는 변수를 만든다(front)

- 리스트(people)의 맨 뒤에서 앞쪽으로 이동하는 변수를 만든다(back)

- 반복문에서 back은 항상 왼쪽으로 한 칸씩 움직인다.

- people의 front 번째 값과 back번 째 값을 더해서 limit보다 작거나 같다면 front를 한 칸 오른쪽으로 이동시킨다.

- front보다 back이 작아질 때까지 진행한다.

 

1번 테스트 케이스

people = [70, 50, 80]

limit =  100

 

1. people을 정렬시킨다.

[70, 50, 80] -> [50, 70, 80]

 

2. 

- back과 front를 더하면 limit인 100보다 크므로 front는 가만히 있는다.

- back을 왼쪽으로 한 칸 움직이자

 

3.

- back과 front를 더하면 limit인 100보다 크므로 front는 가만히 있는다.

- back을 왼쪽으로 한 칸 움직이자.

 

- back과 front를 더하면 limit인 100보다 크므로 front는 가만히 있는다.

- back을 왼쪽으로 한 칸 움직이자. (back을 왼쪽으로 움직이면 front보다 앞에 위치하므로, 반복문을 종료한다.)

 

2번 테스트 케이스

people = [30, 40, 50, 60]

limit =  100

 

1. people 정렬한다. [30, 40, 50, 60] -> [30, 40, 50, 60]

 

2.

- back과 front를 더하면 limit인 100보다 작으므로 front도 오른쪽으로 한 칸 움직이자.

- back을 왼쪽으로 한 칸 움직이자. 

 

3.

- back과 front를 더하면 limit인 100보다 작으므로 front도 오른쪽으로 한 칸 움직이자.

- back을 왼쪽으로 한 칸 움직이자. (back이 front보다 앞으로 가게 되므로 반복문이 종료된다.)

 

코드

def solution(people, limit):
    answer = 0
    people = sorted(people)
    front = 0
    back = len(people)-1
    while front < back:
        answer += 1
        if people[front] + people[back] <= limit:
            front += 1
        back -= 1
    return answer

본 풀이는 유튜브 강의를 토대로 작성했습니다.

 

2239번: 스도쿠

스도쿠는 매우 간단한 숫자 퍼즐이다. 9×9 크기의 보드가 있을 때, 각 행과 각 열, 그리고 9개의 3×3 크기의 보드에 1부터 9까지의 숫자가 중복 없이 나타나도록 보드를 채우면 된다. 예를 들어 다

www.acmicpc.net


문제 분석

- 스도쿠를 푸는 알고리즘을 작성해야 한다.

- 스도쿠의 각 칸에는 가로/세로/ 3 x 3 박스 내에 1~9까지 곂치는 수가 존재하지 않아야 한다.

 

본 문제를 풀이할 때 주의사항이 있다.

"가로/세로/ 3 x 3 박스 내에 1~9까지 곂치는 수"를 고려하여 문제를 풀었을 때 답이 나오지 않는 경우가 존재한다

그럴 때는 이전 칸으로 돌아가서 조건에 맞는 다른 수로 수정해야 한다.

 

따라서 이 문제는 백 트래킹을 사용해야 한다.


알고리즘

1. 스도쿠에 빈 공간(0)이 있는지 확인한다. 

2. 빈 공간이 없으면 스도쿠가 완성됐으므로 종료한다.

3. 빈 공간이 있으면 빈 공간(col, row)이 어딘지 말한다.

4. 빈 공간에 어떤 값(1~9)이 들어갈 수 있는지 탐색한다.

 - 찾았다면 스도쿠에 채워넣는다.

 - 채워넣을 수 있는 게 없다면 백 트래킹 한다.

 

스도쿠에 빈 공간 확인하기

1. 스도쿠 전체를 탐색하며 빈 공간(0)이 발견되면 해당 좌표를 리턴한다.

2. 스도쿠에서 빈 공간이 발견되지 않으면, None을 리턴한다.

 

빈 공간에 들어갈 수 있는 값인지 식별하기

빈 공간에 들어갈 수 있는 값인지 식별하기 위해서는 "가로 / 세로 / 3 x 3 박스"를 탐색해야 한다.

 

1. 가로 탐색

스도쿠의 column을 고정시키고 row 방향으로 이동 탐색을 진행한다.

들어가고자 하는 값이 발견되면 False를 리턴한다.

 

2. 세로 탐색

스도쿠의 row을 고정시키고 col 방향으로 이동 탐색을 진행한다.

들어가고자 하는 값이 발견되면 False를 리턴한다.

 

3. 3 x 3 박스 탐색

1. 탐색이 시작될 지점을 계산한다

2. 탐색시작 지점에서부터 3 x 3 지점을 탐색한다.

1. (7, 4) 지점이 속한 박스 영역의 시작 지점을 찾는다고 가정하자.

2. 왼쪽 그림의 경우 박스의 시작 지점은 (6, 3)이다.

3. 박스 영역의 시작 지점을 찾는 공식은 (컬럼좌표//3 * 3, 로우좌표//3 *3)이다.

("a//b"는 a와 b를 나눴을 때 몫과 나머지 중에 몫만 출력한다)

 

 

 

 

 

 


코드

import sys
# sys.stdin = open("C:/Users/JIn/PycharmProjects/coding_Test/input.txt", "rt")

def pretty_print():
    for i in range(9):
        for j in range(9):
            print(board[i][j], end='')
        print()

def find_empty():
    for i in range(9):
        for j in range(9):
            if board[i][j] == 0:
                return i, j
    return None, None

def valid(col, row, val):
    # 가로 축 점검
    for i in range(9):
        if board[col][i] == val:
            return False

    # 세로 축 점검
    for i in range(9):
        if board[i][row] == val:
            return False

    # 3x3 박스 점검
    box_col = col // 3 * 3
    box_row = row // 3 * 3
    for i in range(3):
        for j in range(3):
            if board[box_col+i][box_row+j] == val:
                return False
    return True

def solution():
    col, row = find_empty()
    if col is None:
        return True
    else:
        for i in range(1, 10):
            if valid(col, row, i):
                board[col][row] = i
                if solution():
                    return True
                board[col][row] = 0
        return False

if __name__ == '__main__':
    board = [list(map(int, input())) for _ in range(9)]
    solution()
    pretty_print()

 

www.acmicpc.net/problem/19942

 

19942번: 다이어트

식재료 N개 중에서 몇 개를 선택해서 이들의 영양분(단백질, 탄수화물, 지방, 비타민)이 일정 이상이 되어야 한다. 아래 표에 제시된 6가지의 식재료 중에서 몇 개를 선택해서 이들의 영양분의 각

www.acmicpc.net


풀이전략

이 문제는 두 가지 조건을 충족시켜야 하는 완전 탐색 문제입니다.

1. 최소 성분기준 충족 

2. 최소비용

 

완전 탐색에 사용된 조건은 다음과 같습니다.

1. 최소비용을 넘은 경우의 수에 대해서는 진행을 멈춥니다.

2. 탐색이 시작될 때 마다 최소 성분기준을 충족시키는지 확인합니다.

  - 최소 성분을 기준을 통과했다면 최소 비용과 사용된 인덱스 번호들을 갱신합니다.

3. 모든 경우의 수 탐색이 끝나면 종료됩니다.

 

아래 그림은  완전탐색에 사용한 노드 그래프입니다.

 

코드

import sys
# sys.stdin = open("C:/Users/JIn/PycharmProjects/coding_Test/input.txt", "rt")


def passOrNot(v, usedIdx):
    global mn
    for i in range(4):
        if req[i] > v[i]:
            return False
    mn = v[4]
    mnIdx.clear()
    mnIdx.extend(usedIdx)
    return


def DFS(L, v, usedIdx):
    global mn
    if v[4] >= mn:
        return
    if passOrNot(v, usedIdx):
        return
    if L == n:
        return
    else:
        usedIdx.append(L+1)
        for i in range(5):
            v[i] += data[L][i]
        DFS(L + 1, v, usedIdx)

        usedIdx.pop()
        for i in range(5):
            v[i] -= data[L][i]
        DFS(L + 1, v, usedIdx)

if __name__ =='__main__':
    n = int(input())
    req = list(map(int, input().split()))
    data = [list(map(int, input().split())) for i in range(n)]
    mn = 9999999
    mnIdx = []
    res = DFS(0, [0]*5, [])

    if mn == 9999999:
        print(-1)
    else:
        print(mn)
        for i in mnIdx:
            print(i, end=' ')

www.acmicpc.net/problem/5585

 

5585번: 거스름돈

타로는 자주 JOI잡화점에서 물건을 산다. JOI잡화점에는 잔돈으로 500엔, 100엔, 50엔, 10엔, 5엔, 1엔이 충분히 있고, 언제나 거스름돈 개수가 가장 적게 잔돈을 준다. 타로가 JOI잡화점에서 물건을 사

www.acmicpc.net


풀이전략

1. 거스름 돈의 액수를 구한다. : 1000 - N

2. 500엔, 100엔, 50엔, 5엔, 1엔 순으로 반복문을 돌린다.

3. 아래와 같은 순서로 반복을 진행하고, N이 0이 됐을 때 반복문을 종료한다.

코드

import sys
# sys.stdin = open("C:/Users/JIn/PycharmProjects/coding_Test/input.txt", "rt")

change = 1000 - int(input())
numPaper = 0
paperTypes = [500, 100, 50, 10, 5, 1]

for paperType in paperTypes:
    a, b = divmod(change, paperType)
    numPaper += a
    change = b
    if change == 0:
        print(numPaper)
        break

 

 

 

 

10282번: 해킹

최흉최악의 해커 yum3이 네트워크 시설의 한 컴퓨터를 해킹했다! 이제 서로에 의존하는 컴퓨터들은 점차 하나둘 전염되기 시작한다. 어떤 컴퓨터 a가 다른 컴퓨터 b에 의존한다면, b가 감염되면

www.acmicpc.net


문제 설명

다익스트라 알고리즘을 사용하는 문제입니다.

 

- 첫 줄의 3 3 1는 각각 컴퓨터 수(n), 의존성 수(d), 감염원번호(c)를 의미합니다.

- 두 번째 줄부터 의존성 수(d)만큼 데이터가 주어집니다.

- 각각은 a, b, s로 "b는 a에 의존하며 s초 후에 감염된다"는 의미를 가지고 있습니다.

- 감염의 시작 c입니다.

 

 

왼쪽과 같은 그림에서 감염이 일어나는 순서는 다음과 같습니다.

- 1은 감염원이므로, 0초 후에 감염이 됩니다.

- 2는 2초 후에 감염이 됩니다

- 3은 8초가 아닌 6초 후에 감염이 됩니다.

 

 

 

각 변수의 조건 범위는 다음과 같습니다.

(1 ≤ n ≤ 10,000, 1 ≤ d ≤ 100,000, 1 ≤ c ≤ n)

(1 ≤ a, b ≤ n, a ≠ b, 0 ≤ s ≤ 1,000)

 

리턴하고자 하는 답은 감염된 컴퓨터의 수와 감염되는데 걸리는 시간입니다.

 

알고리즘 설명

1. 다익스트라 알고리즘으로 문제를 해결하기 위해 아래와 같은 형식으로 데이터를 입력 받습니다.

이 리스트를 data라고 부르겠습니다.

 

 

- 1번 컴퓨터를 2와 3이 의존합니다. 각각은 2초와 8초 후에 감염됩니다.

- 0번 컴퓨터는 없습니다. 문제풀이 편의상 1~(N+1)의 리스트를 만들었습니다.

 

 

2. 각 노드로 갈 수 있는 최소시간을 갱신할 리스트를 만듭니다. 이 리스트를 dy라고 부르겠습니다.

 

dy

 

- timepassed는 x초 후에 감염되는 컴퓨터(a)를 의미합니다.

- 0번 컴퓨터는 없습니다. 문제풀이. 편의상 만들었습니다.

 

다익스트라 알고리즘은 각 노드로 가는 최소값을 구하는 문제입니다.

각 노드는 반복적으로 실행됨으로써 최소값으로 갱신됩니다.

 

문제에서 주어진대로 반복의 시작점은 감염원 번호(c)인 1번 컴퓨터입니다.

따라서 1번 컴퓨터를 0으로 설정합니다.

나머지는 10,000,000으로 설정합니다.

 

10,000,000인 이유는 문제 조건에서 최대 컴퓨터의 개수는 10,000, 감염에 걸리는 최대 시간은 1000이라고 했습니다.

따라서 최종적으로 감염에 걸릴 수 있는 최대 시간은 10,000*1,000인 10,000,000입니다.

 

3. Heap 자료구조를 사용할 리스트를 만듭니다. 이 리스트를 q라고 부르겠습니다.

 

q

 

Heap을 위해 사용할 리스트에 (s+timePassed, a) 형태로 값을 입력받습니다.

s+timePassed는 a번 컴퓨터가 감염될 때까지 걸릴 최종 시간을 의미합니다.

 

 

예를 들어 왼쪽 그림의 경우에는,

2번 컴퓨터는 2초 후에 감염됩니다.

3번 컴퓨터는 2초 + 4초인 6초 후에 감염됩니다.

 

 

 

 

4. 반복문을 수행합니다.

(1) 1번 컴퓨터에서 감염이 시작됩니다.

 

dy

 

(2) data의 1번 컴퓨터에 있는 (2,2), (3,8)를 모조리 꺼냅니다.

 

data

 

(2-1) 2번 컴퓨터의 감염시간인 2초와 dy[1]를 더한 값은 10,000,000보다 작으므로, 

dy[2]를 2+dy[1]인 2로 갱신합니다.

 

dy

 

(2-2) 최소 값을 우선으로 리턴하기 위해 q에 값을 넣습니다.

 

q

 

(2-3) 3번 컴퓨터의 감염시간인 8초와 dy[1]를 더한 값은 10,000,000보다 작으므로, 

dy[3]을 8+dy[1]인 8로 갱신합니다.

 

dy

 

(2-4) 힙 큐 알고리즘을 위한 q에 값을 추가합니다.

 

q

 

(3) q에 있는 최소시간은 2이므로, 힙 큐 알고리즘에 의해 (2,2)를 꺼냅니다.

 

q

 

(3-1) data[2]의 값은 (3,4)입니다. 2초 + 4초인 6초는 dy[3]인 8초보다 작으므로, dy[3]을 6초로 갱신합니다.

 

dy

 

(3-2) q에 값을 추가합니다.

 

q

 

(4) q에 있는 최소시간은 6이므로 (6,3)을 꺼냅니다.

 

q

 

(4-1) data[3]에는 비교대상이 없으므로 dy, queue 리스트의 변화가 없습니다.

 

(5) q에 있는 (8,3)은 이미 dy[3]보다 크므로, 비교/갱신을 진행하지 않고 꺼냅니다.

 

(6) 답을 리턴합니다.

- 1000000을 제외하고 가장 큰 값은 최종 감염시간을 나타냅니다 : 6

- 1000000을 제외한 값의 개수는 감염된 컴퓨터의 수를 나타냅니다 : 3

 

dy

문제풀며 작성한 구상도

문제 풀면서 작성했던 구상도입니다. 혹시 위의 설명으로 부족하신 분은 참고해서 봐주세요

코드

import sys
import heapq

# sys.stdin = open("C:/Users/JIn/PycharmProjects/coding_Test/input.txt", "rt")
numTestcase = int(input())

for _ in range(numTestcase):
    n, d, c = map(int, input().split())    # n : 컴퓨터 수, d : 의존성 수, c : 감염원
    data = [[] for _ in range(n+1)]  # '인덱스'는 의존받는 대상(b), '값'은 [(x초 후 감염, 의존하는 대상(a))]
    for _ in range(d):
        a, b, s = map(int, input().split())    # 감염 방향: b -> a, s초 후 감염
        data[b].append((s, a))

    # 다익스트라 알고리즘
    dy = [100000000] * (n+1)    # 몇 초 후에 감염되는지 저장
    dy[c] = 0    # 감염원(c)은 0초 후에 감염
    q = [(0, c)]
    while q:
        timePassed, infectedCp = heapq.heappop(q)
        if dy[infectedCp] < timePassed:
            continue
        for s, a in data[infectedCp]:
            if dy[a] > s + timePassed:
                dy[a] = s + timePassed
                heapq.heappush(q, (s+timePassed, a))
    time = -1
    nCp = 0
    for i in range(1, n+1):
        if dy[i] != 100000000:
            time = max(time, dy[i])
            nCp += 1
    print(nCp, time)

 

 

+ Recent posts