zoukankan      html  css  js  c++  java
  • poj1860

    题意:有若干种货币,某些币种之间可兑换,给出各种兑换时的汇率和手续费,任何兑换都是双向的,但是两个方向的汇率和手续费可能不同,并告知你现在拥有的货币种类(只拥有一种)及数量,问是否可以通过货币建兑换最后回到本币种后钱数有所增加。

    分析:普通的货币兑换一般都是用floyd。但是本题除了汇率还多出一个条件——手续费,所以不能简单地使用floyd。我用的是spfa求最长路,检查是否有环路。从自己的币种出发,如果发现正环,那么则可以不停地走环路以增加自己手中的价值,又因为所有的路都是双向的,所以当手中的价值增加的足够多之后是一定可以回到自己原有的币种的。又因为正环能使价值达到正无穷,所以回去之后价值一定增加。所以本题转化为判断是否有正环。

    View Code
    #include <iostream>
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    #define maxm 105
    #define maxn 105
    
    struct Edge
    {
        int v, next;
        double rate, commission;
    }edge[maxm * 2];
    
    int n, m;
    int s;
    int head[maxn];
    double v;
    double dist[maxn];
    bool in_queue[maxn];
    int push_cnt[maxn];
    int q[maxn];
    int edge_cnt;
    
    void addedge(int a, int b, double r, double c)
    {
        edge[edge_cnt].v = b;
        edge[edge_cnt].next = head[a];
        edge[edge_cnt].rate = r;
        edge[edge_cnt].commission = c;
        head[a] = edge_cnt++;
    }
    
    void input()
    {
        edge_cnt = 0;
        memset(head, -1, sizeof(head));
        scanf("%d%d%d%lf", &n, &m, &s, &v);
        s--;
        for (int i = 0; i < m; i++)
        {
            int a, b;
            double r, c;
            scanf("%d%d", &a, &b);
            a--;
            b--;
            scanf("%lf%lf", &r, &c);
            addedge(a, b, r, c);
            scanf("%lf%lf", &r, &c);
            addedge(b, a, r, c);
        }
    }
    
    bool spfa(int s)
    {
        for (int i = 0; i < n; i++)
            dist[i] = -1;
        dist[s] = v;
        memset(in_queue, 0, sizeof(in_queue));
        memset(push_cnt, 0, sizeof(push_cnt));
        int front, rear;
        front = 0;
        rear = 0;
        q[rear++] = s;
        in_queue[s] = true;
        push_cnt[s] = 1;
        
        while (front != rear)
        {
            int u = q[front++];
            if (front == maxn)
                front = 0;
            in_queue[u] = false;
            double cur = dist[u];
            for (int i = head[u]; ~i; i = edge[i].next)
            {
                int v = edge[i].v;
                double r = edge[i].rate;
                double c = edge[i].commission;
                double temp = (cur - c) * r;
                if (temp > dist[v])
                {
                    dist[v] = temp;
                    //printf("%d %.2f\n", v, dist[v]);
                    if (in_queue[v])
                        continue;
                    q[rear++] = v;
                    if (rear == maxn)
                        rear = 0;
                    in_queue[v] = true;
                    push_cnt[v]++;
                    if (push_cnt[v] > n)
                        return true;
                }
            }
            if (dist[s] > v)
                return true;
        }        
        return false;
    }
    
    int main()
    {
        //freopen("t.txt", "r", stdin);
        input();
        if (spfa(s))
            puts("YES");
        else
            puts("NO");
        return 0;
    }
  • 相关阅读:
    pyftpdlib 搭建FTP服务器
    numpy 解一道简单数学题
    python 实现词云
    个人的毕业长足---- 暴走北京
    Tensorflow of GPU, hello fish by version 0.8.
    图像识别
    用一个Inception v3 架构模型实现简单的迁移学习(译:../tensorflow/tensorflow/examples/image_retraining/retrain.py)
    19.液晶屏的原理
    18.DMA-6410
    17.DMA-2440
  • 原文地址:https://www.cnblogs.com/rainydays/p/2974296.html
Copyright © 2011-2022 走看看