poj 1860 Currency Exchange

 重新拾起最短路算法

  题意 : 就是套汇的问题,汇率Rab, 增加了一个手续费 Cab 。。。。。。。每次的结果是 (本金 - 手续费) * 汇率,而且一个人拥有的钱的类型是已知的,拥有的value 钱的个数也是已知的, 问你能不能增值。



输入 :

3 2 1 20.0                         //钱种类个数  汇率的个数,拥有第几种钱, 拥有多少钱
1 2 1.00 1.00 1.00 1.00            //钱a, 钱b, rab, cab, rba, cba
2 3 1.10 1.00 1.10 1.00


想法: 应用bellman-ford :

一种货币就是图上的一个点

一个“兑换点”就是图上两种货币之间的一个兑换环,相当于“兑换方式”M的个数,是双边

唯一值得注意的是权值,当拥有货币A的数量为V时,A到A的权值为K,即没有兑换

而A到B的权值为(V-Cab)*Rab

本题是“求最大路径”,之所以被归类为“求最小路径”是因为本题题恰恰与bellman-Ford算法的松弛条件相反,求的是能无限松弛的最大正权路径,但是依然能够利用bellman-Ford的思想去解题。

因此初始化d(S)=V 而源点到其他店的距离(权值)初始化为无穷小(0),当s到其他某点的距离能不断变大时,说明存在最大路径

代码:

#include<iostream>
using namespace std;
int n,m,s,all;
double v,dis[101];

struct node
{
       int a;
       int b;
       double r;
       double c;
}exc[202];
bool bellman()
{
    memset(dis,0,sizeof(dis));
    dis[s]=v;
    bool flag;
    for(int i=1;i<=n-1;i++)
    {
       flag=false;
       for(int j=0;j<all;j++)
          if(dis[exc[j].b]<(dis[exc[j].a]-exc[j].c)*exc[j].r)
          {
             dis[exc[j].b] = (dis[exc[j].a] - exc[j].c) * exc[j].r;
             flag=true;
          }
          if(!flag) break;
     }
     for(int k=0;k<all;k++)
     {
       if(dis[exc[k].b]<(dis[exc[k].a]-exc[k].c)*exc[k].r)
           return true;
     }
     return false;
}
     
int main()
{
   int a,b,i;
   double rab,cab,rba,cba;
   while(cin>>n>>m>>s>>v)
   {
      all=0;
      for(i=0;i<m;i++)
      {
        cin>>a>>b>>rab>>cab>>rba>>cba;
        exc[all].a=a;
        exc[all].b=b;
        exc[all].r=rab;
        exc[all++].c=cab;
        exc[all].a=b;
        exc[all].b=a;
        exc[all].r=rba;
        exc[all++].c=cba;
   }
   if(bellman()) cout<<"YES"<<endl;
   else cout<<"NO"<<endl;
 }
 return 0;
}
       
       

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值