标签:
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