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 ...
随机推荐
- java集合---迭代器iterator
一:ArraryList 最终继承超级接口Collection,Colection接口继承Iterator接口. public interface Collection<E> exten ...
- expdp导出时报错ora-16000
一.问题现象:在对数据库进行expdp导出时发生报错ora-16000,脚本如下: nohup expdp "'/ as sysdba'" schemas=shp DIRECTOR ...
- Scala(二):元组、数组、映射
元组:Tuple,不同类型值的聚集.将固定数量的项目组合在一起,以便它们可以作为一个整体传递. 与数组或列表不同,元组可以容纳不同类型的对象,但它们也是不可变的.元祖的实际类型取决于它的分量的类型,比 ...
- Word里面怎么取消全文每个标题前面都有的这个点
Word里标题前面的那个点,如图1所示看起来觉得很不舒服,该怎么把它取消呢?(本测试环境是Win 10 64位系统,Microsoft Office家庭和学生版 2016) 图1 选中所有标题,如图2 ...
- Tomcat7 新的数据库连接池Tomcat jdbc pool介绍和配置
Tomcat 在 7.0 以前的版本都是使用commons-dbcp做为连接池的实现,但是 dbcp存在一些问题: (1)dbcp 是单线程的,为了保证线程安全会锁整个连接池 (2)dbcp 性能不佳 ...
- 【转载】MSXML应用总结 开发篇(下)
原文:http://blog.sina.com.cn/s/blog_48f93b530100eq4b.html 三.查询XML文档节点 这部分属于“读”XML文档并做节点遍历,由于担心加上实例会占用过 ...
- PKUWC2019题解
这里其实只放一下题面和一些提示,大家评一评有几道题可做 题面全部蒯自xzz的博客 Day 1 T1 题面 一个有向图,每一条边可能存在也可能不存在,求拓扑序列数量的期望乘\(2^m\) 没有重边自环, ...
- let和var定义变量的区别
使用 let 语句声明一个变量,该变量的范围限于声明它的块中. 可以在声明变量时为变量赋值,也可以稍后在脚本中给变量赋值. 使用 let 声明的变量,在声明前无法使用,否则将会导致错误. 如果未在 ...
- NGUI可展开列表的实现
本文来自网易云社区 作者:汪毅军 最近使用了NGUI做了下可展开列表,其主要思路如下:首先最外层使用Scroll view以达到滑动效果,然后列表使用UITable进行排列,最后通过点击Item控制I ...
- Django + Ansible 主机管理(有源码)
本文给大家介绍如何利用 Django + Ansible 进行 Web 项目管理. Django介绍 一个可以使 Web 开发工作愉快并且高效的 Web 开发框架,能够以最小的代价构建和维护高质量 ...