8044 : 통화 환전
•시간제한: 2.000 S
•메모리제한: 256 MB
•제출: 0
•통과: 0
•만든사람: suakii
문제 설명
여러 통화와 이들을 환전할 수 있는 사설 환전소 정보가 주어집니다. 환전소 $AB$는 통화 $A$를 통화 $B$로 환전해 줄 때, 환율(Rate) $R_{AB}$와 수수료(Commission) $C_{AB}$를 적용합니다.
어떤 사람이 갖고 있던 통화 $A$의 금액 $V$를 환전소를 통해 통화 $B$로 환전하면, 최종 돌려받는 금액은 $(V - C_{AB}) \times R_{AB}$가 됩니다. 환전 시 수수료가 수중에 남은 돈보다 많거나 같으면 환전할 수 없습니다.
처음에 Nick은 $S$번 통화를 $V$만큼 보유하고 있습니다. Nick이 다른 통화들을 거쳐 다시 $S$번 통화로 돌아왔을 때, 처음 갖고 있던 돈 $V$보다 더 많은 돈을 보유할 수 있는 환전 경로(즉, 자산을 계속 늘릴 수 있는 무한 루프)가 존재하는지 판별하는 프로그램을 작성하시오.
[제약 조건]
• $1 \le S \le N \le 100$
• $1 \le M \le 100$
• $10^{-3} \le V \le 10^3$
• $0.01 \le R \le 100.0$, $0.0 \le C \le 100.0$
어떤 사람이 갖고 있던 통화 $A$의 금액 $V$를 환전소를 통해 통화 $B$로 환전하면, 최종 돌려받는 금액은 $(V - C_{AB}) \times R_{AB}$가 됩니다. 환전 시 수수료가 수중에 남은 돈보다 많거나 같으면 환전할 수 없습니다.
처음에 Nick은 $S$번 통화를 $V$만큼 보유하고 있습니다. Nick이 다른 통화들을 거쳐 다시 $S$번 통화로 돌아왔을 때, 처음 갖고 있던 돈 $V$보다 더 많은 돈을 보유할 수 있는 환전 경로(즉, 자산을 계속 늘릴 수 있는 무한 루프)가 존재하는지 판별하는 프로그램을 작성하시오.
[제약 조건]
• $1 \le S \le N \le 100$
• $1 \le M \le 100$
• $10^{-3} \le V \le 10^3$
• $0.01 \le R \le 100.0$, $0.0 \le C \le 100.0$
입력 설명
첫째 줄에 통화의 종류 $N$, 환전소의 수 $M$, Nick이 처음에 가진 통화 번호 $S$, 그리고 초기 자산 $V$가 공백으로 구분되어 주어집니다.
($1 \le S \le N \le 100$, $1 \le M \le 100$, $V$는 소수점 이하 네 자리까지의 실수, $10^{-3} \le V \le 10^3$)
다음 $M$개의 줄에 각 환전소의 정보가 주어집니다. 각 줄은 6개의 값 $A, B, R_{AB}, C_{AB}, R_{BA}, C_{BA}$로 이루어져 있으며, 이는 $A$와 $B$ 간에 양방향 환전이 가능하고 각각의 환율과 수수료를 뜻합니다. ($0.01 \le R \le 100.0$, $0.0 \le C \le 100.0$)
($1 \le S \le N \le 100$, $1 \le M \le 100$, $V$는 소수점 이하 네 자리까지의 실수, $10^{-3} \le V \le 10^3$)
다음 $M$개의 줄에 각 환전소의 정보가 주어집니다. 각 줄은 6개의 값 $A, B, R_{AB}, C_{AB}, R_{BA}, C_{BA}$로 이루어져 있으며, 이는 $A$와 $B$ 간에 양방향 환전이 가능하고 각각의 환율과 수수료를 뜻합니다. ($0.01 \le R \le 100.0$, $0.0 \le C \le 100.0$)
출력 설명
자산을 무한히 늘릴 수 있는 환전 루프가 존재한다면
YES를 출력하고, 그렇지 않다면 NO를 출력합니다.
입력 예시
COPY
복사되었습니다!
복사되었습니다!
3 2 1 20.0
1 2 1.0 1.0 1.0 1.0
2 3 1.1 1.0 1.1 1.0
출력 예시
COPY
복사되었습니다!
복사되었습니다!
YES
도움
이 문제는 가중치를 곱하고 더하는 형태의 음수 사이클(여기서는 돈이 늘어나므로 양수 사이클)을 판정하는 최단/최장 경로 문제입니다.
벨만-포드(Bellman-Ford) 알고리즘을 사용합니다.
초기 거리를 모두 0으로 두고 $dist[S] = V$로 설정합니다. 모든 노선 간선에 대해 최대값(돈)을 $N-1$번 갱신 연산($dist[v] = \max(dist[v], (dist - C) \times R)$)을 돌립니다. 그 후, 한 번 더 루프를 돌았을 때 어떤 간선에 대해 추가적인 값 갱신이 일어난다면 돈을 계속 늘릴 수 있는 무한 사이클이 존재한다는 뜻이므로
벨만-포드(Bellman-Ford) 알고리즘을 사용합니다.
초기 거리를 모두 0으로 두고 $dist[S] = V$로 설정합니다. 모든 노선 간선에 대해 최대값(돈)을 $N-1$번 갱신 연산($dist[v] = \max(dist[v], (dist - C) \times R)$)을 돌립니다. 그 후, 한 번 더 루프를 돌았을 때 어떤 간선에 대해 추가적인 값 갱신이 일어난다면 돈을 계속 늘릴 수 있는 무한 사이클이 존재한다는 뜻이므로
YES를 판정합니다.