POJ1860 换零钱套利 图论(Bellman-ford)

第一次做图论的题,所以如果下面的话有说的不对的还请见谅。


题目概述:

我们的主人公是一个套利商人,通过在各个零钱兑换点来回来去换钱来得到最大的利润,零钱点的信息有零钱兑换率,手续费。我们只需要判断最后他手里的钱是不是能增加就好了。思想就在于算“正权环”。

算法思想:

我们用Bellman-Ford来做这道题,模型化的方法就是每一种货币当作图的一个点,每一种exchange station作为一条边,边要记载着从哪里,到哪里,change_rate以及手续费。开一个struct来记载这些信息。然后这样组成一张图。

更新每一张图,d[e[j].to]相当于如果当前change之后所拥有的钱,(d[e[j].from]-e[j].rate)*d[j].com相当于新路之后所拥有的钱,然后比较大小如果大的话就更新。model之后相当于是那个图的最长路径。

应该就是一个非常naive的算法,只是我是初学所以不太了解,最后真正的代码和Bellman-Ford的伪代码都十分相似。

交到OJ之后是140多MS,查题解的时候发现有各种十几MS的应该就是所谓的SPFA做的吧。

代码部分:

#include <iostream>

using namespace std;

struct edge{
	int from, to;
	double rate, com;
};

edge e[217];
double d[117];
int n, m,s;
double v;
int main() {
	cin >> n >> m >> s >> v;
	for (int i = 0; i < m * 2; i += 2){
		int tmp_from, tmp_to; double tmp_rate, tmp_com;
		cin >> tmp_from >> tmp_to >> tmp_rate >> tmp_com;
		e[i].from = tmp_from; e[i].to = tmp_to;
		e[i].rate = tmp_rate; e[i].com = tmp_com;
		cin >> tmp_rate >> tmp_com;
		e[i + 1].from = tmp_to; e[i + 1].to = tmp_from;
		e[i + 1].rate = tmp_rate; e[i + 1].com = tmp_com;
	}
	d[s] = v;

	//Bellman-ford algorithm
	for (int i = 0; i < n-1; i++){
		for (int j = 0; j < 2 * m; j++){
			if (d[e[j].to] < (d[e[j].from] - e[j].com)*e[j].rate) {
				d[e[j].to] = (d[e[j].from] - e[j].com)*e[j].rate;
			}
		}
	}
	bool flag = false;
	for (int j = 0; j < 2 * m; j++){
		if (d[e[j].to] < (d[e[j].from] - e[j].com)*e[j].rate) {
			flag = true;
			break;
		}
	}
	if (flag) cout << "YES" << endl;
	else cout << "NO" << endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值