POJ 1860 Currency Exchange bellman求正权路

来源:互联网 发布:玩游戏 知乎 编辑:程序博客网 时间:2024/05/18 03:07

Currency Exchange
Time Limit: 1000MS Memory Limit: 30000KTotal Submissions: 27195 Accepted: 10072

Description

Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be several points specializing in the same pair of currencies. Each point has its own exchange rates, exchange rate of A to B is the quantity of B you get for 1A. Also each exchange point has some commission, the sum you have to pay for your exchange operation. Commission is always collected in source currency. 
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 RAB, CAB, RBA and CBA - 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

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
For each point exchange rates and commissions are real, given with at most two digits after the decimal point, 10-2<=rate<=102, 0<=commission<=102
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 104

Output

If Nick can increase his wealth, output YES, in other case output NO to the output file.

Sample Input

3 2 1 20.01 2 1.00 1.00 1.00 1.002 3 1.10 1.00 1.10 1.00

Sample Output

YES

Source

Northeastern Europe 2001, Northern Subregion

    题意:a和b货币相互兑换存在不同的手续费和不同的兑换比例。a兑换b、b兑换a的汇率也是不同的。求最终能否使得最终的货币数大于最初的货币数。

    分析:该题可以抽象为求最大路径,判断是否存在正环,如果存在正环的话,那么可以一直重复此循环可以使得拥有货币量一直增大。其他理解见代码注释,AC代码:

//将a 到 b的边的值抽象为 经过这次a b 转换后剩下的值 #include<stdio.h>#include<string.h>using namespace std;const int maxn=105;int n,m,cnt, s;double  v; //注意v是double 类型 //n表示有n种货币//m表示有m中兑换方式//s指现在持有货币//v指持有的s货币的数量struct moneychange{int a;int b;double r;//兑换比率double c;//手续费} me[maxn*2];//moneychange  //无向图 double dis[maxn];bool  bellman(){memset(dis,0,sizeof(dis));//初始化值为最小  dis[s]=v; bool flag;for(int j=1; j<=n-1; j++){for(int i=0; i<cnt; i++)if(dis[me[i].b]<(dis[me[i].a]-me[i].c)*me[i].r){dis[me[i].b]=(dis[me[i].a]-me[i].c)*me[i].r;flag=true;}if(!flag)//若没有更新则退出循环 break;}     //该题中如果最终的结果能大于原来的值 那么说明一定存在 负权路    //只要存在负权路就可以无限增大 第一次走完值肯定比原来的大  //所以该题转换为 判断是否存在负权路 for(int i=0; i<cnt; i++)//若此时值还能增大说明存在 这类题目中的负权路  最大值可以无限增大 if(dis[me[i].b]<(dis[me[i].a]-me[i].c)*me[i].r)return true;return false;}int main(){while(~scanf("%d%d%d%lf",&n,&m,&s,&v)){cnt=0;int ta,tb;double trab,tcab,trba,tcba;while(m--){scanf("%d%d%lf%lf%lf%lf",&ta,&tb,&trab,&tcab,&trba,&tcba);me[cnt].a=ta;me[cnt].b=tb;me[cnt].r=trab;me[cnt++].c=tcab;//无向图 b 到 a的边同样存在 me[cnt].a=tb;me[cnt].b=ta;me[cnt].r=trba;me[cnt++].c=tcba;}if(bellman()) //如果存在的话 printf("YES\n");elseprintf("NO\n");}return 0;}
    特记下,以备后日回顾。

1 0
原创粉丝点击