题目大意:假設有A,B兩種貨幣,要將A換成B,須透過匯率Rab和手續費Cab,因此實際得到B貨幣=(A-Cab)*Rab元。
第一行輸入N, M, S, V,N表示共有N種貨幣(1<=N<=100),M表示底下有M行,每一行有六個數字A,B,Rab,Cab,Rba,Cab,Rab表示A換成B的匯率,Cab表示A換成B需要扣除的手續費,Rba和Cba同理。現在Nick有第S種貨幣V元,題目問Nick透過不斷交換貨幣,然後最後換回第S種貨幣的時候能否大於V元?
解题思路:Bellman-ford改一改,只要能够无限松弛,就符合题意(我这里优化了一下Bellman-ford,就是不能松弛了,就退出松弛循环(这道题可以直接判断不行了), 感觉有点像冒泡的优化
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #define MAXVERTEXNUM 500 5 #define INF 1000000 6 using namespace std; 7 8 struct E 9 { 10 int a, b; 11 double exchange_currency, tips; 12 }Edge[MAXVERTEXNUM]; 13 int Nv, Ne, s, num = 0; 14 double org, dist[MAXVERTEXNUM]; 15 16 bool Bellman_Ford() 17 { 18 for (int i = 1; i < Nv; ++i) 19 { 20 bool flag = false; 21 for (int j = 0; j < num; ++j) 22 { 23 if (dist[Edge[j].b] < (dist[Edge[j].a] - Edge[j].tips) * Edge[j].exchange_currency) 24 { 25 dist[Edge[j].b] = (dist[Edge[j].a] - Edge[j].tips) * Edge[j].exchange_currency; 26 flag = true; 27 } 28 } 29 if (!flag) 30 return false;//写break还要快一些,黑人问号??? 31 } 32 33 for (int i = 0; i < num; ++i) 34 if (dist[Edge[i].b] < (dist[Edge[i].a] - Edge[i].tips) * Edge[i].exchange_currency) 35 return true; 36 37 return false; 38 } 39 40 int main() 41 { 42 ios::sync_with_stdio(false); 43 44 cin >> Nv >> Ne >> s >> org; 45 memset(dist, 0, sizeof(dist)); 46 dist[s] = org; 47 //init 48 49 for (int i = 1; i <= Ne; ++i) 50 { 51 int V1, V2; 52 double t1, t2, t3, t4; 53 cin >> V1 >> V2 >> t1 >> t2 >> t3 >> t4; 54 Edge[num].a = V1, Edge[num].b = V2; 55 Edge[num].exchange_currency = t1; 56 Edge[num++].tips = t2; 57 Edge[num].a = V2, Edge[num].b = V1; 58 Edge[num].exchange_currency = t3; 59 Edge[num++].tips = t4; 60 } 61 62 if (Bellman_Ford()) 63 cout << "YES" << endl; 64 else 65 cout << "NO" << endl; 66 67 return 0; 68 }