标签:
Input
The first line of the input contains four numbers: N - the number of currencies, M - the number of exchange points, S - the number of currency Nick has and V - the quantity of currency units he has. The following M lines contain 6 numbers each - the description of the corresponding exchange point - in specified above order. Numbers are separated by one or more spaces. 1<=S<=N<=100, 1<=M<=100, V is real number, 0<=V<=103.
Output
If Nick can increase his wealth, output YES, in other case output NO to the output file.
Sample Input
3 2 1 20.02 3 1.10 1.00 1.10 1.00
YES
Northeastern Europe 2001, Northern Subregion
题目大意:有N种货币,货币之间可以按汇率交换,同时还需要收手续费,当你用100A货币去交换B货币,
假如A到B的汇率为29.75,手续费为0.39,则你可以得到(100-0.39)*29.75 = 2963.3975的B货币。货币
可以一直重复交换,问:能否通过兑换货币之后,增加你手中货币的价值,则输出"YES",否则输出"NO"。
思路:把N种货币看成图上的N个点,当你有数量为V的货币A时,
货币AB之间的权值就是——(V-手续费)*A到B的汇率
这道题就可以转换为求图是否还有可无限增大(含有正权回路)的最大路径。那么怎么来判断是否含有正权回
路。可以用BellmanFord算法的思想来做。
BellmanFord是来求最短路径,并判断是否存在负权回路。这里用BellmanFord来求最长路径,并判断是否
存在正权回路。
<span style="font-family:Microsoft YaHei;">#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int MAXN = 110; const int MAXM = 220; const int INF = 0xffffff0; struct EdgeNode { int to; //连接的b点 int next; // double rate;// double cost; }Edges[MAXM]; int Head[MAXN]; double Dist[MAXN]; //M——兑换点个数 N——货币种数 S——手里持有第S种货币 V——持有的第S种货币资金 bool BellmanFord(int M,int N,int S,double V) { Dist[S] = V; for(int i = 1; i < N; ++i) { for(int j = 1; j <= N; ++j) { for(int k = Head[j]; k != -1; k = Edges[k].next) //寻找最长路径 { if(Dist[Edges[k].to] < (Dist[j]-Edges[k].cost)*Edges[k].rate) Dist[Edges[k].to] = (Dist[j]-Edges[k].cost)*Edges[k].rate; } } } for(int j = 1; j <= N; ++j) { for(int k = Head[j]; k != -1; k = Edges[k].next) { if(Dist[Edges[k].to] < (Dist[j]-Edges[k].cost)*Edges[k].rate) //S到其他路径能一直增大时,说明存在最长路径 return true; } } return false; } int main() { int N,M,S,u,v; double V,Rab,Cab,Rba,Cba; while(~scanf("%d%d%d%lf",&N,&M,&S,&V)) { int id = 0; memset(Head,-1,sizeof(Head)); memset(Dist,0,sizeof(Dist)); //初始为0,不为INF,因为BellmanFord是用来找负环的,这里用来找是否存在正环 memset(Edges,0,sizeof(Edges)); for(int i = 0; i < M; ++i) { scanf("%d%d%lf%lf%lf%lf",&u,&v,&Rab,&Cab,&Rba,&Cba); Edges[id].to = v; Edges[id].rate = Rab; Edges[id].cost = Cab; Edges[id].next = Head[u]; Head[u] = id++; Edges[id].to = u; Edges[id].rate = Rba; Edges[id].cost = Cba; Edges[id].next = Head[v]; Head[v] = id++; } if(BellmanFord(id,N,S,V)) printf("YES\n"); else printf("NO\n"); } return 0; } </span>
POJ1860 Currency Exchange【BellmanFord算法】【求正权回路】
标签:
原文地址:http://blog.csdn.net/lianai911/article/details/42472531