POJ 1860 Currency Exchange(Bellman-Ford)

Description
给定n种货币,某些货币之间可以相互兑换,现在给定一些兑换规则,问能否从某一种货币开始兑换,经过一些中间货币之后,最后兑换回这种货币,并且得到的钱比之前的多
Input
第一行为四个整数n,m,s,v分别表示货币种类,兑换规则,初始货币种类和初始货币数量,之后m行每行为一个兑换规则,每行首先是两个整数a,b表示a货币和b货币可以兑换,然后是四个浮点数表示a换b的汇率,手续费,和b换a的汇率,手续费
Output
若通过一系列兑换钱变多则输出YES,否则输出NO
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
Solution
一种货币就是图上的一个点,一个“兑换点”就是图上两种货币之间的一个兑换环,相当于“兑换方式”m的个数,是双边。A到B的权值为
(A的数量-A换B的手续费)*A换B的汇率
本题是“求最大路径”,之所以被归类为“求最小路径”是因为本题题恰恰与bellman-Ford算法的松弛条件相反,求的是能无限松弛的最大正权路径,但是依然能够利用bellman-Ford的思想去解题。因此初始化cost(s)=v, 而源点到其他店的距离(权值)初始化为无穷小(0),当s到其他某点的距离能不断变大时,说明存在最大路径
Code

#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 210
double cost[maxn];//源点到其他点的权值 
int node[maxn][2];//记录可兑换货币的类型,即一维兑换二维 
double value[maxn][2];//一维记录汇率,二维记录手续费 
int tol;//记录兑换规则数量 

bool Bellman_Ford(int s,int n,double v)
{
    for(int i=1;i<=n;i++)//源点到其他点的权值初始化为0 
        cost[i]=0;
    cost[s]=v;//源点自身权值为v 
    for(int i=1;i<n;i++)
    {
        bool flag=false;//标志变量 
        for(int j=0;j<tol;j++)//寻找能变大的路径 
        {
            int l=node[j][0],r=node[j][1];
            if(cost[r]<(cost[l]-value[j][1])*value[j][0])//存在能变大的路径 
            {
                flag=true;
                cost[r]=(cost[l]-value[j][1])*value[j][0];//更新源点到此点的权值 
            }
        }
        if(!flag)//不存在能变大的路径 
            return false;
    }
    for(int i=0;i<tol;i++)//存在能不断变大的路径 
        if(cost[node[i][1]]<(cost[node[i][0]]-value[i][1])*value[i][0])
            return true;
    return false;//不存在能不断变大的路径 
}
int main()
{
    int n,m,s;
    double v;
    while(scanf("%d%d%d%lf",&n,&m,&s,&v)!=EOF)
    {
        tol=0;
        int a,b;
        double c,d,e,f;
        while(m--)
        {
            scanf("%d%d%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f);
            node[tol][0]=a;
            node[tol][1]=b;
            value[tol][0]=c;
            value[tol][1]=d;
            tol++;
            node[tol][0]=b;
            node[tol][1]=a;
            value[tol][0]=e;
            value[tol][1]=f;
            tol++;
        }
        if(Bellman_Ford(s,n,v))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}

你可能感兴趣的:(POJ 1860 Currency Exchange(Bellman-Ford))