목차

신제품 개발

ps
링크acmicpc.net/…
출처BOJ
문제 번호31250
문제명신제품 개발
레벨플래티넘 1
분류

구현

시간복잡도O(min(NM,K))
인풋사이즈N<=500, M<=100000, K<=10^18
사용한 언어PyPy
제출기록128324KB / 1000ms
최고기록1000ms
해결날짜2024/01/17

풀이

코드

"""Solution code for "BOJ 31250. 신제품 개발".

- Problem link: https://www.acmicpc.net/problem/31250
- Solution link: http://www.teferi.net/ps/problems/boj/31250

Tags: [simulation]
"""

import sys

SOURCE = 0
MOD = 1_000_000_007
INF = float('inf')


def main():
    N, M, K = [int(x) for x in sys.stdin.readline().split()]
    A = [int(x) for x in sys.stdin.readline().split()]
    edges = [(INF, N, N)]
    for _ in range(M):
        u, v, B = [int(x) for x in sys.stdin.readline().split()]
        edges.append((B, u - 1, v - 1))

    edges.sort(reverse=True)
    c, u = 0, SOURCE
    move_count = K
    successors = list(range(N))
    order, inc_sum = [-1] * (N + 1), [-1] * (N + 1)
    order[N] = INF
    order[u] = cur_order = path_beg = 0
    inc_sum[u] = cur_inc_sum = 0

    if edges[-1][0] == 0:
        _, x, y = edges.pop()
        successors[x] = y

    while move_count:
        move_count -= 1
        u = successors[u]
        c += A[u]
        cur_order += 1
        cur_inc_sum += A[u]

        if c >= edges[-1][0]:
            while c >= edges[-1][0]:
                _, x, y = edges.pop()
                successors[x] = y
            path_beg = cur_order
            cur_inc_sum = 0

        if order[u] >= path_beg:
            cycle_beg = order[u]
            while order[edges[-1][1]] < cycle_beg:
                _, x, y = edges.pop()
                successors[x] = y

            next_b = edges[-1][0]
            cycle_inc = cur_inc_sum - inc_sum[u]
            cycle_size = cur_order - order[u]
            if cycle_inc == 0 or next_b == INF:
                cycle_count = move_count // cycle_size
            else:
                cycle_count = min(
                    (next_b - c) // cycle_inc, move_count // cycle_size
                )
            c += cycle_inc * cycle_count
            move_count -= cycle_size * cycle_count

            if c == next_b:
                _, x, y = edges.pop()
                successors[x] = y
            path_beg = cur_order
            cur_inc_sum = 0

        order[u], inc_sum[u] = cur_order, cur_inc_sum

    print(u + 1, c % MOD)


if __name__ == '__main__':
    main()