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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章