【POJ1860】Currency Exchange
题目链接:http://poj.org/problem?id=1860
题意是,现在有几种钞票,可以在这些钞票中进行兑换,兑换时必须将手中的钞票全部兑换成另一种,给出一些兑换的方式,每种方式有固定的钞票类型,手续费和兑换比例,最开始你有一些某种类型的钞票,问是否能是手中的钞票增多(最后仍需兑换成原来的钞票)。
问题的本质是在图中找到一个正环,使手中钞票增加。可以使用bellman-ford算法的优化版本——SPFA算法求解
SPFA是一种常用的求最短路算法,其平a均时间复杂度为O(m)(n为点的数量,m为边的数量),在某些图上可能达到O(nm),由于这种算法的高效性和易于实现,被广泛的用于求解最短路问题,同时也适用于图中有负权边的求解。
SPFA是对bellman-ford的一种优化。我们知道,在dijk算法中,应用了贪心原则,在每一轮中只选用离起始点最近的点,用它的出边进行更新(也称为“松弛”操作)。而在bellman-ford算法中,使用所有边完成一次更新,也就是说,对于每个点均需遍历所有边,这使得bellman-ford算法适用性更广,可用于负权边,负环的求解,但其代价是大量的无用更新操作。而SPFA算法利用了一个性质:松弛操作必定只会发生在最短路径前导节点松弛成功过的节点上。使用队列进行优化,节省了这些无用操作。
值得一提的是,SPFA算法是由我校段凡丁老师于1994年提出的,这里是原论文地址:[1]。
将题目转化为寻找正环后,很容易写出代码:
#include
#include
#include