poj1860 Currency Exchange(java + bellman-Ford)

本文介绍了一种使用Bellman-Ford算法检测货币兑换网络中是否存在盈利循环的方法。通过构建图模型,利用负权边循环特性判断经过一系列货币兑换后是否能获得超过初始本金的收益。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package test;

import java.util.Scanner;

/**问题请参考http://poj.org/problem?id=1860
 * @author rayli

 * @date:2014-7-27 下午4:16:26
 * 题意 :有N种货币,同时有M个货币兑换站点,每个站点支持两种货币A,B之间的相互兑换,
 * 六个数字(A,B,Rab,Cab,Rba,Cba)表示它的属性,
 * 假如A->B,则A的量Va可换得的B货币数Vb则,Vb=(Va-Cab)*Rab;先有一个含有s种货币V元,问他能否经过各种兑换后,换得的s货币多于V元
 *
 */

class exchange
{
    public    int a;//货币a
    public    int b;//货币b
    public    double r;// 汇率
    public    double c;//手续费

}

public class CurrencyExchange
{
    exchange map[];
    double dis[];
    int n;
    int s;
    double v;
    int e;//边
    
    void input()
    {
        Scanner cin = new Scanner(System.in);
         n = cin.nextInt();//货币种数
        
        int m = cin.nextInt();//兑换点数量
        
        map = new exchange[2*m];
        dis = new double[2*m+1];//刚开始定义的是2m,但提交不过,所以后后定义数组时应该适当的开大点
         s = cin.nextInt();//持有第s种货币
         v = cin.nextDouble();//持有的s货币的本金
        
        e = 0;
        for(int i=0; i<m; i++)
        {
            int a = cin.nextInt();
            int b = cin.nextInt();
            
            map[e] = new exchange();
            map[e].a = a;
            map[e].b = b;
            map[e].r = cin.nextDouble();
            map[e].c = cin.nextDouble();
            e++;
            int tmp = e;
            map[tmp] = new exchange();
            map[tmp].a = b;
            map[tmp].b = a;
            map[tmp].r = cin.nextDouble();
            map[tmp].c = cin.nextDouble();
            e++;
        }
        cin.close();
    }
    boolean bellmanford()
    {
        dis[s] = v;
        
        for(int i=1; i<=n; i++)
        {
            boolean flag = false;
            
            for(int j=0; j<e; j++)
            {
                if(dis[map[j].b] < (dis[map[j].a] - map[j].c) * map[j].r)
                {
                    dis[map[j].b] = (dis[map[j].a] - map[j].c) * map[j].r;
                    flag = true;
                }
            }
            
            if(!flag)
                break;
        }
        
        for(int k=0; k<e; k++)
        {
            if(dis[map[k].b] < (dis[map[k].a] - map[k].c) * map[k].r)
            {
                return true;
            }
        }
        
        
        return false;
        
    }
    
    void output()
    {
        if(bellmanford())
            System.out.println("YES");
        else
            System.out.println("NO");
    }
    public static void main(String args[])
    {
        CurrencyExchange ce = new CurrencyExchange();
        
        ce.input();
        ce.output();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值