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, 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.
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, 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
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<=10 3.
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.
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
If Nick can increase his wealth, output YES, in other case output NO to the output file.
Sample Input
3 2 1 20.0 1 2 1.00 1.00 1.00 1.00 2 3 1.10 1.00 1.10 1.00
Sample Output
YES
题意:有m家银行,每家银行能兑换两种货币,兑换货币需要手续费,且有货币兑换率,例如,如果你想在兑换点把100美元兑换成俄罗斯卢布,兑换率是29.75,佣金是0.39,你会得到(100-0.39)*29.75=2963.3975卢布。这个世界
共有n中货币。你的目的是将你的货币兑换成第n种货币后,你手中的钱比你原来的多。输入第一行,四个数:n种货币,m家银行,你现在的货币是第s种货币,你现在有数量为v的钱数。往后为m行,每行有六个数字:银行能兑换的货币种类
a,b,从a到b的汇率c和手续费d,从b到a的汇率e和手续费f.
思路:兑换你手中的钱在各个银行中,如果兑换后钱数并没有减少,就是赚了。可以转换为:每种货币为一个点,点之间的连线为边,如果你从起点到终点的过程中没有负权,则整个过程过后,你的钱并不会减少。
利用Bellman-Ford
算法的思想,但你要求的是没有负权,只需要对Bellman-Ford
算法做一些改变即可。
代码:
1 #include <cstdio> 2 #include <fstream> 3 #include <algorithm> 4 #include <cmath> 5 #include <deque> 6 #include <vector> 7 #include <queue> 8 #include <string> 9 #include <cstring> 10 #include <map> 11 #include <stack> 12 #include <set> 13 #include <sstream> 14 #include <iostream> 15 #define mod 998244353 16 #define eps 1e-6 17 #define ll long long 18 #define INF 0x3f3f3f3f 19 using namespace std; 20 21 22 //dis用来存放到起点之间的距离 23 double dis3[110]; 24 //存的起点和终点 25 int qiz[210][2]; 26 //存款的手续费 27 double sxf[210][2]; 28 //边的数量 29 int ans; 30 31 //修改后的bellman算法,用于求正环 32 //start表示初始点,n表示点的个数,v表示初始钱数 33 bool bellman(int start,int n,double v) 34 { 35 //由于dis3数组为double类型,所以用for来初始化 36 for(int i=0;i<=n;i++) 37 { 38 dis3[i]=0; 39 } 40 //初始化起点 41 dis3[start]=v; 42 //遍历n-1次 43 for(int i=1;i<n;i++) 44 { 45 //flag优化,false表示有负权 46 bool flag=false; 47 //遍历所有边 48 for(int j=1;j<=ans;j++) 49 { 50 int a=qiz[j][0]; 51 int b=qiz[j][1]; 52 //如果转换货币后钱数增加,则代表这两点之间为正权 53 if(dis3[b]<((dis3[a]-sxf[j][1])*sxf[j][0])) 54 { 55 dis3[b]=((dis3[a]-sxf[j][1])*sxf[j][0]); 56 flag=true; 57 } 58 } 59 //如果遍历所有边后数据增加,表示有负权 60 if(!flag) 61 { 62 return false; 63 } 64 } 65 //遍历n-1遍后,应当得出所有数据 66 for(int i=1;i<=ans;i++) 67 { 68 //但钱数还能增加,表示有正权 69 if(dis3[qiz[i][1]]<((dis3[qiz[i][0]]-sxf[i][1])*sxf[i][0])) 70 { 71 return true; 72 } 73 } 74 return false; 75 } 76 int main() 77 { 78 //n表示货币种类,m表示银行的数量,s表示你有的货币种类 79 int n,m,s; 80 //v表示你有的钱数 81 double v; 82 //初始边为1 83 ans=1; 84 scanf("%d %d %d %lf",&n,&m,&s,&v); 85 //a,b记录货币种类 86 int a,b; 87 //c,e为汇率,d,f为手续费 88 double c,d,e,f; 89 for(int i=1;i<=m;i++) 90 { 91 scanf("%d %d %lf %lf %lf %lf",&a,&b,&c,&d,&e,&f); 92 //记录从a到b的数据 93 qiz[ans][0]=a; 94 qiz[ans][1]=b; 95 sxf[ans][0]=c; 96 sxf[ans][1]=d; 97 ans++; 98 //记录从b到a的数据 99 qiz[ans][0]=b; 100 qiz[ans][1]=a; 101 sxf[ans][0]=e; 102 sxf[ans][1]=f; 103 ans++; 104 } 105 //判断是否有负环 106 if(bellman(s,n,v)) 107 { 108 printf("YES "); 109 } 110 else 111 { 112 printf("NO "); 113 } 114 }