我们的城市有几个货币兑换点。让我们假设每一个点都只能兑换专门的两种货币。可以有几个点,专门从事相同货币兑换。每个点都有自己的汇率,外汇汇率的A到B是B的数量你1A。同时各交换点有一些佣金,你要为你的交换操作的总和。在来源货币中总是收取佣金。 例如,如果你想换100美元到俄罗斯卢布兑换点,那里的汇率是29.75,而佣金是0.39,你会得到(100 - 0.39)×29.75=2963.3975卢布。 你肯定知道在我们的城市里你可以处理不同的货币。让每一种货币都用唯一的一个小于N的整数表示。然后每个交换点,可以用6个整数表描述:整数a和b表示两种货币,a到b的汇率,a到b的佣金,b到a的汇率,b到a的佣金。 nick有一些钱在货币S,他希望能通过一些操作(在不同的兑换点兑换),增加他的资本。当然,他想在最后手中的钱仍然是S。帮他解答这个难题,看他能不能完成这个愿望。
第一行四个数,N,表示货币的总数;M,兑换点的数目;S,nick手上的钱的类型;V,nick手上的钱的数目;1<=S<=N<=100, 1<=M<=100, V 是一个实数 0<=V<=103. 接下来M行,每行六个数,整数a和b表示两种货币,a到b的汇率,a到b的佣金,b到a的汇率,b到a的佣金(0<=佣金<=102,10-2<=汇率<=102)
4.
如果nick能够实现他的愿望,则输出YES,否则输出NO。
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
YES
这个题写的还是很悲催的,一开始觉得不会错,然而交了好多wa,卡了四个多小时,就因为传参的时候,把double型,传成了int型,导致精度损失,以至于一直wa。
题意是我在Vjudge上粘贴的(如有冒犯原翻译者,还请原谅),因为这道题会出现负边权,所以不能用Dijkstra,数据范围100以内,所以用Floyd或者Bellman都可以,接下来有两种写法。
Floyd, 跑两遍Floyd,第一遍是确定a转化成b,得到的多少钱,然后再进行一次转化,如果第二次的前多于第一次的钱(只要满足一个即可)就输出YES
#include <stdio.h> #include <string.h> double dis[105]; double mon[105]; double e1[105][105]; double e2[105][105]; bool Floyd(int v, int n, int s) { for(int i = 1; i <= n; i++) { dis[i] = mon[i]; } for(int k = 1; k <= n; k++) { for(int i = 1; i <= n; i++) { for(int j = 1; j <= n; j++) { if(mon[j] < (mon[i] - e2[i][j])*e1[i][j]) mon[j] = (mon[i]-e2[i][j])*e1[i][j]; } } } for(int i = 1; i <= n; i++) { if(mon[i] > dis[i]) return true; } return false; } int main() { int N, M, S; double V; int a, b; double rat1, com1, rat2, com2; scanf("%d %d %d %lf", &N, &M, &S, &V); for(int i = 0; i < M; i++) { scanf("%d %d %lf %lf %lf %lf", &a, &b, &rat1, &com1, &rat2, &com2); e1[a][b] = rat1; e2[a][b] = com1; e1[b][a] = rat2; e2[b][a] = com2; } mon[S] = V; Floyd(V, N, S); if(Floyd(V, N, S)) printf("YES\n"); else printf("NO\n"); return 0; }
Bellman,将所拥有的钱兑换成所有可以兑换的钱,并且把金额记录下来,然后再将兑换过的钱,兑换成原来的钱,判断两次钱的数目大小即可
#include <stdio.h> #include <string.h> struct node{ int s, e; double rat, com; void Node(int a, int b, double c, double d) { s = a; e = b; rat = c; com = d; } }map[220]; double dis[105]; bool Bellman(double v, int n, int s, int m) { for(int i = 1; i <= n; i++) { dis[i] = 0; } dis[s] = v; for(int i = 1; i < n; i++) { bool flag = false; for(int j = 0; j < m; j++) { int u = map[j].s; int v = map[j].e; if(dis[v] < (dis[u] - map[j].com)*map[j].rat) { flag = true; dis[v] = (dis[u] - map[j].com)*map[j].rat; } } if(!flag) return false; } for(int j = 0; j < m; j++) { int u = map[j].s; int v = map[j].e; if(dis[v] < (dis[u] - map[j].com)*map[j].rat) { return true; } } return false; } int main() { int N, M, S; double V; int a, b; double rat1, com1, rat2, com2; scanf("%d %d %d %lf", &N, &M, &S, &V); int t = 0; for(int i = 0; i < M; i++) { scanf("%d %d %lf %lf %lf %lf", &a, &b, &rat1, &com1, &rat2, &com2); map[t++].Node(a, b, rat1, com1); map[t++].Node(b, a, rat2, com2); } if(Bellman(V, N, S, t)) printf("YES\n"); else printf("NO\n"); return 0; }