POJ1860 Currency Exchange (BellmanFord)

题意分析

给出货币相互对换的汇率,求经过若干次对换之后,能否使得原来的货币变多。

将每种货币看做成一个点,将对换看做是边,使用BellmanFord判断是否含有正环即可。
因为正环的含义就是,可以多次走这个环,使得每次对换后相应的货币变多。

代码总览

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int nmax = 10000;
const double INF = 999999999.0;
double dis[nmax];
int head[nmax];
int tot = 0;
int n,m,s;
double v;
struct Edge{
    int to,nxt;
    double val,tip;
    Edge(){}
    Edge(int _u, int _v, double _val, double _tip ){
        to = _v; nxt = head[_u]; val = _val; tip = _tip;
    }
};
Edge edge[nmax<<1];
void init(){
    tot = 0;
    memset(head,-1,sizeof head);
    memset(edge,0,sizeof edge);
}
inline void add(int _u, int _v, double _val, double _tip){
    edge[tot] = Edge(_u,_v,_val,_tip);
    head[_u] = tot ++;
}
bool Bellman(int st){
    for(int i = 1;i<=n;++i) dis[i] = 0.0;
    dis[st] = v;
    for(int k = 2;k<=n;++k){
        for(int i = 1;i<=n;++i){
            for(int j = head[i];j!=-1;j = edge[j].nxt){
                int to = edge[j].to;
                dis[to] = max(dis[to], (dis[i] - edge[j].tip) * edge[j].val);
            }
        }
        if(dis[st] > v) return true; // 经过循环后货币变多
    }
    for(int i  = 1;i<=n;++i){ // 最后判断正环
        for(int j = head[i];j!=-1;j = edge[j].nxt){
            int to = edge[j].to;
            if(dis[to] < (dis[i] - edge[j].tip) * edge[j].val )
                return true;
        }
    }
    return false;

}
int main(){
    while(scanf("%d %d %d %lf",&n,&m,&s,&v)!=EOF){
        init();
        int f,t; double r1,t1,r2,t2;
        for(int i = 0;i<m;++i){
            scanf("%d %d %lf %lf %lf %lf",&f,&t,&r1,&t1,&r2,&t2);
            add(f,t,r1,t1); add(t,f,r2,t2);
        }
        bool isok =  Bellman(s);
        if(isok) printf("YES\n");
        else printf("NO\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值