POJ-1860 Currency Exchange

Posted on 2021-11-22 11:23  Capterlliar  阅读(11)  评论(0编辑  收藏  举报

传送门

题意:给定起始拥有货币种类为s,拥有数量为v。现有n种不同货币,m种货币转换。货币转换为双向,但两种转换汇率r和手续费c不同。询问是否能够换一圈,最后s的数目增长。(问能否钱从天上来

解:由于要求换一圈货币种类仍为s,所以要求有环。由于不能亏,所以要求是正环。spfa找环即可。

注:spfa找正环temp>dis[to],找负环temp<dis[to]。入队次数超过n,即它可以一直变小就是有环

代码:

#include<stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
#define ll long long
#define maxx 105
#define inf 0x7fffffff
//#define int long long
int n,m,s;
double v;
struct edge{
    int u,v;
    double r,c;
    int nxt;
}e[maxx*2];
int head[maxx]={0},cnt=0;
void add(int u,int v,double r,double c){
    e[++cnt].u=u;
    e[cnt].v=v;
    e[cnt].r=r;
    e[cnt].c=c;
    e[cnt].nxt=head[u];
    head[u]=cnt;
}
double dis[maxx];
int vis[maxx]={0},in[maxx]={0};
int spfa(int x){
    for(int i=1;i<=n;i++)
        dis[i]=0;
    queue<int> q;
    q.push(x);
    vis[x]=1;dis[x]=v;in[x]++;
    while(!q.empty()){
        int now=q.front();
        q.pop();
        vis[now]=0;
        for(int i=head[now];i;i=e[i].nxt){
            int to=e[i].v;
            double f=(dis[now]-e[i].c)*e[i].r;
            if(f>dis[to]){
                dis[to]=f;
                in[to]++;
                if(in[to]>=n)
                    return 1;
                if(!vis[to]){
                    vis[to]=1;
                    q.push(to);
                }
            }
        }
    }
    return 0;
}
signed main() {
    scanf("%d%d%d%lf",&n,&m,&s,&v);
    for(int i=0;i<m;i++){
        int x,y;
        double r1,c1,r2,c2;
        scanf("%d%d%lf%lf%lf%lf",&x,&y,&r1,&c1,&r2,&c2);
        add(x,y,r1,c1);
        add(y,x,r2,c2);
    }
    if(spfa(s))
        printf("YES\n");
    else
        printf("NO\n");
    return 0;
}
View Code

//poj也没有万能头qaq

//但是vj上有中文版本就又快乐起来了