Bellman_ford 算法 Currency Exchange POJ1860
Posted joeylee97
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bellman_ford 算法 Currency Exchange POJ1860相关的知识,希望对你有一定的参考价值。
Bellman_ford算法用于寻找正环或者负环!
算法导论:
24.1 The Bellman-Ford algorithm
The Bellman-Ford algorithm solves the single-source shortest-paths problem in the general case in which edge weights may be negative. Given a weighted, directed graph G = (V, E) with source s and weight function w : E → R, the Bellman-Ford algorithm returns a boolean value indicating whether or not there is a negative-weight cycle that is reachable from the source. If there is such a cycle, the algorithm indicates that no solution exists. If there is no such cycle, the algorithm produces the shortest paths and their weights.
The algorithm uses relaxation, progressively decreasing an estimate d[v] on the weight of a shortest path from the source s to each vertex v ∈ V until it achieves the actual shortest-path weight δ(s, v). The algorithm returns TRUE if and only if the graph contains no negative-weight cycles that are reachable from the source.
BELLMAN-FORD(G, w, s) 1 INITIALIZE-SINGLE-SOURCE(G, s) 2 for i ← 1 to |V[G]| - 1 3 do for each edge (u, v) ∈ E[G] 4 do RELAX(u, v, w) 5 for each edge (u, v) ∈ E[G] 6 do if d[v] > d[u] + w(u, v) 7 then return FALSE 8 return TRUE
Figure 24.4 shows the execution of the Bellman-Ford algorithm on a graph with 5 vertices. After initializing the dand π values of all vertices in line 1, the algorithm makes |V| – 1 passes over the edges of the graph. Each pass is one iteration of the for loop of lines 2-4 and consists of relaxing each edge of the graph once. Figures 24.4(b)-(e) show the state of the algorithm after each of the four passes over the edges. After making |V|- 1 passes, lines 5-8 check for a negative-weight cycle and return the appropriate boolean value. (We’ll see a little later why this check works.)
Figure 24.4: The execution of the Bellman-Ford algorithm. The source is vertex s. The d values are shown within the vertices, and shaded edges indicate predecessor values: if edge (u, v) is shaded, then π[v] = u. In this particular example, each pass relaxes the edges in the order (t, x), (t, y), (t, z), (x, t), (y, x), (y, z), (z, x), (z, s), (s, t), (s, y). (a) The situation just before the first pass over the edges. (b)-(e) The situation after each successive pass over the edges. The d and π values in part (e) are the final values. The Bellman-Ford algorithm returns TRUE in this example.
The Bellman-Ford algorithm runs in time O(V E), since the initialization in line 1 takes Θ(V) time, each of the |V| – 1 passes over the edges in lines 2-4 takes Θ(E) time, and the for loop of lines 5-7 takes O(E) time.
题目:
For example, if you want to exchange 100 US Dollars into Russian Rubles at the exchange point, where the exchange rate is 29.75, and the commission is 0.39 you will get (100 - 0.39) * 29.75 = 2963.3975RUR.
You surely know that there are N different currencies you can deal with in our city. Let us assign unique integer number from 1 to N to each currency. Then each exchange point can be described with 6 numbers: integer A and B - numbers of currencies it exchanges, and real R AB, C AB, R BA and C BA - exchange rates and commissions when exchanging A to B and B to A respectively.
Nick has some money in currency S and wonders if he can somehow, after some exchange operations, increase his capital. Of course, he wants to have his money in currency S in the end. Help him to answer this difficult question. Nick must always have non-negative sum of money while making his operations.
Input
For each point exchange rates and commissions are real, given with at most two digits after the decimal point, 10 -2<=rate<=10 2, 0<=commission<=10 2.
Let us call some sequence of the exchange operations simple if no exchange point is used more than once in this sequence. You may assume that ratio of the numeric values of the sums at the end and at the beginning of any simple sequence of the exchange operations will be less than 10 4.
Output
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<sstream> #include<algorithm> #include<queue> #include<deque> #include<iomanip> #include<vector> #include<cmath> #include<map> #include<stack> #include<set> #include<fstream> #include<memory> #include<list> #include<string> using namespace std; typedef long long LL; typedef unsigned long long ULL; #define MAXN 105 #define N 33 #define MOD 10000007 #define INF 1000000009 const double eps = 1e-9; const double PI = acos(-1.0); /* 即寻找从给定状态开始有没有正环 */ struct edge { int u, v; double cost, rate; edge(int _u,int _v,double _cost,double _rate):u(_u),v(_v),cost(_cost),rate(_rate){} }; vector<edge> E; double dis[MAXN]; int n, m, s; double num; bool Bellman_ford(int s,double num) { memset(dis, 0, sizeof(dis)); dis[s] = num; for (int i = 0; i < n; i++) { bool f = false;//不能松弛 for (int j = 0; j < E.size(); j++) { int u = E[j].u, v = E[j].v; double c = E[j].cost, r = E[j].rate; if (dis[v] < (dis[u] - c)*r) { f = true; dis[v] = (dis[u] - c)*r; } } if (!f) return false; } for(int j=0;j<E.size();j++) if (dis[E[j].v] < (dis[E[j].u] - E[j].cost)*E[j].rate) { return true; } return false; } int main() { while (scanf("%d%d%d%lf", &n, &m, &s, &num) != EOF) { int a, b; double rab, cab, rba, cba; for (int i = 0; i < m; i++) { scanf("%d%d%lf%lf%lf%lf", &a, &b, &rab, &cab, &rba, &cba); E.push_back(edge(a, b, cab, rab)); E.push_back(edge(b, a, cba, rba)); } if (Bellman_ford(s, num)) printf("YES\\n"); else printf("NO\\n"); } }
以上是关于Bellman_ford 算法 Currency Exchange POJ1860的主要内容,如果未能解决你的问题,请参考以下文章
POJ-1860 Currency Exchange( Bellman_Ford, 正环 )