POJ-1860 Currency Exchange

2 篇文章 0 订阅
2 篇文章 0 订阅

这里写图片描述

题目大意

你有好几种货币,是否能够通过不断地换似的s币的钱变多。(若A,B两种货币的汇率为 x,手续费为 y,w 单位的 A 货币,能换成 (w-y)*x个单位的 B 货币 )。

第一行输入四个整数,分别表示N货币总数,M兑换点的数目,S nick手上钱的类型,V nick手上钱的数目。

接下来M行每行6个整数,前两个表示A和B两种货币,接下来两个表示A换成B的汇率和手续费,最后两个表示B换成A的汇率和手续费。

题解
明显是判环的题目,我写的是spfa判环。
spfa判环和普通的spfa没啥区别,只是要记录每个点入队列的次数,如果大于等于 n 次就说明走进环里了(如果没有环,除去 i 点本身还有 n-1 个点,即使这 n-1 每个点都可以走到 i 一次,那么最多也只走到 n-1 次。而有环的情况下(理论上)会遍历到无数次)。

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=105,maxm=105;
bool vis[maxn];
int n,m,s,h[maxn];
double v,f[maxn],q[maxn],c[maxn][maxn],p[maxn][maxn];
bool spfa(int x,double y)
{
    q[1]=x;int til=1,hea=0;
    memset(f,230,sizeof f);
    f[x]=y;
    memset(h,0,sizeof h);
    memset(vis,0,sizeof vis);
    while (hea!=til)
    {
        vis[x=q[(++hea)%=maxn]]=0;
        for (int i=1;i<=n;i++)
          if (c[x][i]>0&&(f[x]-p[x][i])*c[x][i]>f[i])
          {
              f[i]=(f[x]-p[x][i])*c[x][i];
              if (vis[i]) continue;h[i]++;
              if (h[i]>n) return 1;
              vis[i]=1;q[(++til)%=maxn]=i;
          }
    }
    return 0;
}
int main()
{
    while (~scanf("%d%d%d%lf",&n,&m,&s,&v))
    {
        memset(c,230,sizeof c);
        for (int i=1;i<=m;i++)
        {
            int x,y;scanf("%d%d",&x,&y);
            scanf("%lf%lf%lf%lf",&c[x][y],&p[x][y],&c[y][x],&p[y][x]);
        }
        if (spfa(s,v)) printf("YES\n");else printf("NO\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值