Currency Exchange 货币兑换 Bellman-Ford SPFA 判正权回路
Description
Input
Output
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
- 题目意思:有n种货币,货币之间按照汇率交换,当然还要花费一些手续费,货币交换是可以多次重复进行的,问有没有可能经过一系列的货币交换,开始的货币会增加?
当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 B币。
解题思路:这道题可以抽象为图论中的题,将货币种类看为点,货币之间的交换看为有向边,想要货币的金额产生增加,那么必然要有正权回路,即在一条回路上能够一直松弛下去。该题的问题主要在于所给的参数很多,第一行给出了n种货币有m种交换方式,给你第s种货币有V的金额,对于m种的交换方式,从x到y需要汇率rate和手续费commission,从y到x也需要这两个参数。同时这里的松弛递推公式也要发生变化:
- if(dist[edge[i].t]<(dist[edge[i].f]-edge[i].c)*edge[i].r)
- {
- dist[edge[i].t]=(dist[edge[i].f]-edge[i].c)*edge[i].r;
- }
- 因为是需要增加的正权回路,所以如果小于就松弛。
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- using namespace std;
- #define inf 0x3f3f3f3f
- struct Edge
- {
- int f;
- int t;
- double r;
- double c;
- } edge[];
- double dist[];
- int n,m,s,cnt;
- double x;
- int bellman_ford()
- {
- int i,j;
- int flag;
- for(i=; i<=n; i++)
- {
- dist[i]=;
- }
- dist[s]=x;
- for(j=; j<=n; j++)
- {
- flag=;
- for(i=; i<=cnt; i++)
- {
- if(dist[edge[i].t]<(dist[edge[i].f]-edge[i].c)*edge[i].r)
- {
- dist[edge[i].t]=(dist[edge[i].f]-edge[i].c)*edge[i].r;
- flag=;
- }
- }
- if(flag==)
- {
- break;
- }
- }
- return flag;
- }
- int main()
- {
- int i,t;
- int u,v;
- double a1,a2,b1,b2;
- while(scanf("%d%d%d%lf",&n,&m,&s,&x)!=EOF)
- {
- cnt=;
- while(m--)
- {
- scanf("%d%d%lf%lf%lf%lf",&u,&v,&a1,&b1,&a2,&b2);
- edge[cnt].f=u;
- edge[cnt].t=v;
- edge[cnt].r=a1;
- edge[cnt++].c=b1;
- edge[cnt].f=v;
- edge[cnt].t=u;
- edge[cnt].r=a2;
- edge[cnt++].c=b2;
- }
- if(bellman_ford())
- {
- printf("YES\n");
- }
- else
- {
- printf("NO\n");
- }
- }
- return ;
- }
附上使用SPFA的代码
- #include<cstdio>
- #include<cstring>
- #include<queue>
- #include<vector>
- #include<algorithm>
- using namespace std;
- const int INF = 0x3f3f3f3f;
- const int maxs = 1e3+;
- int n,m;
- struct Edge
- {
- int to;
- double rate;
- double com;
- } ;
- double dis[maxs];
- int vis[maxs];
- int cnt[maxs];///用来记录入队列次数
- vector<Edge>maps[maxs];
- void AddEdge(int u,int v,double r,double co)
- {
- Edge t;
- t.to=v;
- t.rate=r;
- t.com=co;
- maps[u].push_back(t);
- }
- int SPFA(int s, double v)
- {
- int i;
- memset(dis,,sizeof());
- memset(vis,,sizeof());
- memset(cnt,,sizeof());
- queue<int>q;
- dis[s]=v;
- vis[s]=;
- cnt[s]++;
- q.push(s);
- while(!q.empty())
- {
- int u=q.front();
- q.pop();
- vis[u]=;
- for(i=; i<maps[u].size(); i++)
- {
- int to=maps[u][i].to;
- double com=maps[u][i].com;
- double rate=maps[u][i].rate;
- if(dis[to]<(dis[u]-com)*rate)
- {
- dis[to]=(dis[u]-com)*rate;
- if(!vis[to])
- {
- vis[to]=;
- cnt[to]++;
- if(cnt[to]>=n)
- {
- return ;
- }
- q.push(to);
- }
- }
- }
- }
- return ;
- }
- int main()
- {
- int s,i;
- double k;
- while(scanf("%d%d%d%lf",&n,&m,&s,&k)!=EOF)
- {
- int a,b;
- double c,d,e,f;
- while(m--)
- {
- scanf("%d%d%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f);
- AddEdge(a,b,c,d);
- AddEdge(b,a,e,f);
- }
- if(SPFA(s,k))
- {
- puts("YES");
- }
- else
- {
- puts("NO");
- }
- }
- return ;
- }
Currency Exchange 货币兑换 Bellman-Ford SPFA 判正权回路的更多相关文章
- poj 1860 Currency Exchange (SPFA、正权回路 bellman-ford)
链接:poj 1860 题意:给定n中货币.以及它们之间的税率.A货币转化为B货币的公式为 B=(V-Cab)*Rab,当中V为A的货币量, 求货币S通过若干此转换,再转换为原本的货币时是否会添加 分 ...
- Currency Exchange POJ - 1860 (spfa判断正环)
Several currency exchange points are working in our city. Let us suppose that each point specializes ...
- POJ1680 Currency Exchange SPFA判正环
转载来源:優YoU http://user.qzone.qq.com/289065406/blog/1299337940 提示:关键在于反向利用Bellman-Ford算法 题目大意 有多种汇币,汇 ...
- 图论 --- spfa + 链式向前星 : 判断是否存在正权回路 poj 1860 : Currency Exchange
Currency Exchange Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 19881 Accepted: 711 ...
- POJ 1860 Currency Exchange(最短路&spfa正权回路)题解
题意:n种钱,m种汇率转换,若ab汇率p,手续费q,则b=(a-q)*p,你有第s种钱v数量,问你能不能通过转化让你的s种钱变多? 思路:因为过程中可能有负权值,用spfa.求是否有正权回路,dis[ ...
- POJ1860-Currency Exchange (正权回路)【Bellman-Ford】
<题目链接> <转载于 >>> > 题目大意: 有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0. ...
- HDU - 1317 ~ SPFA正权回路的判断
题意:有最多一百个房间,房间之间连通,到达另一个房间会消耗能量值或者增加能量值,求是否能从一号房间到达n号房间. 看数据,有定5个房间,下面有5行,第 iii 行代表 iii 号 房间的信息,第一个数 ...
- Bellman_ford货币兑换——正权回路判断
POJ1860 题目大意:你在某一点有一些钱,给定你两点之间钱得兑换规则,问你有没有办法使你手里的钱增多.就是想看看转一圈我的钱能不能增多,出现这一点得条件就是有兑换钱得正权回路,所以选择用bellm ...
- [ACM] hdu 1217 Arbitrage (bellman_ford最短路,推断是否有正权回路或Floyed)
Arbitrage Problem Description Arbitrage is the use of discrepancies in currency exchange rates to tr ...
随机推荐
- C#窗口皮肤制作(二):创建窗口库项目以及最小化、最大化、关闭button的实现
非常高兴有朋友关注这篇博客,同一时候也十分抱歉让关注的朋友久等了,隔上一篇博客也有3个月没有更新,主要是因为3月份辞职,4月份初离职到期离开了北京高德,来到了上海张江.眼下新工作也处于熟悉其中,希望大 ...
- 【LeetCode445】 Add Two Numbers II★★
题目描述: 解题思路: 给定两个链表(代表两个非负数),数字的各位以正序存储,将两个代表数字的链表想加获得一个新的链表(代表两数之和). 如(7->2->4->3)(7243) + ...
- lightbox用法
示例代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- Kali渗透测试2-抓包/DNS工具
转载请注明出处. TCPDUMP:命令行网络抓包工具tcpdump -h tcpdump version 4.9.2 libpcap version 1.8.1 OpenSSL 1.1.0h 27 M ...
- GATK --- wdl 语言
GATK的pipeline使用WDL进行编写 WDL是一种流程管理语言,内置的支持并行,适合编写pipeline 运行wdl脚本需要两步:第一步编辑参数列表对应的json文件,第二步直接运行Cromw ...
- NoSQL入门第二天——Redis入门介绍
一.基本概述 1.是什么 Redis:REmote DIctionary Server (远程字典服务器) 是完全开源免费的,用C语言编写的,遵守BSD协议, 是一个高性能的(key/value)分布 ...
- 2017-2018-1 20155209 实现mypwd
2017-2018-1 20155209 实现mypwd 1 学习pwd命令 2 研究pwd实现需要的系统调用(man -k; grep),写出伪代码 3 实现mypwd 4 测试mypwd 首先使用 ...
- 一个将当前目录下HEX文件的第一行数据删除的程序
为什么要写这样一个函数 在使用SoftConsole开发M3程序时,生成的hex文件,必须要把第一行数据删除,才能在Libero中使用,所以写了这个小工具,这是2.0版本了,第一版是直接删除第一行数据 ...
- Python: C扩展初体验
前言 使用 Python 毋庸置疑减少了很多规则约束和开发成本,让我们能够更加专注于逻辑而非语法.但是得此失彼,开发效率提高了,却带来了运行性能的问题,所以就常常被其他门派追着暴打. 身为一个 pyt ...
- Oracle10g 客户端安装与配置说明
1:百度文库 http://wenku.baidu.com/link?url=bA-FrFMaqxkoifwz-oiPeU5QmMVVJyy8rYDBryhTUCJywpkDS0VNJcObCIM8l ...