""" name: Nicholas Tamassia Honor Code and Acknowledgments: This work complies with the JMU Honor Code. Comments here on your code and submission. """ import math from collections import defaultdict def find_arbitrage(graph: dict[str, dict[str, float]]) -> list[str] | None: weights: dict[str, float] = {c: math.inf for c in graph} prev: dict[str, str | None] = {c: None for c in graph} start: str = list(graph.keys())[0] weights[start] = 0 for _ in range(len(graph) - 1): for src in graph: for dest, rate in graph[src].items(): weight: float = -math.log(rate) if weights[src] + weight < weights[dest]: weights[dest] = weights[src] + weight prev[dest] = src node: str | None = None for src in graph: for dest, rate in graph[src].items(): weight: float = -math.log(rate) if weights[src] + weight < weights[dest]: node = dest prev[dest] = src break if node is not None: break if node is None: return for _ in range(len(graph)): node = prev[node] path = [node] while True: node = prev[node] path.append(node) if node == path[0]: break path.reverse() return path def main(): n: int = int(input().strip()) graph: dict[str, dict[str, float]] = defaultdict(dict) for _ in range(n): vals: list[str] = input().strip().split() src: str = vals[0] dest: str = vals[1] rate: float = float(vals[2]) graph[src][dest] = rate path = find_arbitrage(graph) if path is not None: print("Arbitrage Detected") print(" => ".join(path)) factor = 1.0 for i in range(len(path) - 1): factor *= graph[path[i]][path[i + 1]] print(f"{factor:.5f} factor increase") else: print("No Arbitrage Detected") if __name__ == "__main__": main()