zoukankan      html  css  js  c++  java
  • POJ 1860 汇率 SPFA

    题意

    有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 B币。问s币的金额经过交换最终得到的s币金额数能否增加 货币的交换是可以重复多次的,所以我们需要找出是否存在正权回路,且最后得到的s金额是增加的 怎么找正权回路呢?(正权回路:在这一回路上,顶点的权值能不断增加即能一直进行松弛)

    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
    

    对SPFA算法进行改造,原来的dis改为存的货币的数量,改为求最长路,如果有自环,那么dis会不断增加没有上限

    if(money[v]<(money[u]-E[u][i].fee)*E[u][i].rate){
    	money[v]=(money[u]-E[u][i].fee)*E[u][i].rate;
        if(!vis[v])
    
    #define _CRT_SBCURE_NO_DEPRECATE
    #include <set>
    #include <map>
    #include <cmath>
    #include <queue>
    #include <bitset>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    #define ll long long
    #define mm0(a) memset(a,0,sizeof(a))
    #define mm(a,b) memset(a,b,sizeof(a))
    #define each(a,b,c) for(int a=b;a<=c;a++)
    #define de(x) cout << #x << " " << (x) <<endl
    //#define de(x) cout <<""
    #define rush() int T;scanf("%d",&T);each(kase,1,T)
    #define scan(a,b) scanf("%d%d",&a,&b)
    #define fin(a) scanf("%d",&a)
    using namespace std;
    
    const int maxn = 1e3+5;
    const int INF = 0x3f3f3f3f;
    inline int read(){int s=0;char ch=getchar();for(; ch<'0'||ch>'9'; ch=getchar());for(; ch>='0'&&ch<='9'; ch=getchar())s=s*10+ch-'0';return s;}
    
    /*
    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
    */
    struct Edge{
        int v;
        double fee;
        double rate;
        Edge(int _v,double _fee,double _rate):v(_v),fee(_fee),rate(_rate){}
    };
    vector<Edge>E[maxn];
    void addEdge(int u,int v,double fee,double rate)
    {
        E[u].push_back(Edge(v,fee,rate));
    }
    bool vis[maxn];
    int cnt[maxn];
    double money[maxn];
    
    int n;
    int m;
    int start;
    double init_money;
    bool SPFA(int start,double init_money,int n)
    {
        memset(vis,false,sizeof(vis));//清空vis
        for(int i=1;i<=n;i++)money[i]=0;
        vis[start]=true;
        money[start]=init_money;
        queue<int>Q;
        while(!Q.empty())Q.pop();
        Q.push(start);
        memset(cnt,0,sizeof(cnt));
        cnt[start]=1;
        while(!Q.empty())
        {
            int u=Q.front();
            Q.pop();
            vis[u]=false;
            for(int i=0;i<E[u].size();i++)
            {
                int v=E[u][i].v;
                if(money[v]<(money[u]-E[u][i].fee)*E[u][i].rate){
                    money[v]=(money[u]-E[u][i].fee)*E[u][i].rate;
                    if(!vis[v])
                    {
                        vis[v]=true;
                        Q.push(v);
                        if(++cnt[v]>n)return false;
                    }
                }
            }
    
        }
        return true;
    }
    int main()
    {
        scanf("%d%d%d%lf",&n,&m,&start,&init_money);
        each(i,1,m)
        {
            int a,b;
            double rab,cab,rba,cba;
            scan(a,b);
            scanf("%lf%lf%lf%lf",&rab,&cab,&rba,&cba);
            addEdge(a,b,cab,rab);
            addEdge(b,a,cba,rba);
        }
        if(!SPFA(start,init_money,n))
            cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    
    }
    
  • 相关阅读:
    Oracle 11g服务详细介绍及哪些服务是必须开启的?
    分析函数Ratio_to_report使用
    在datagrid中,IE浏览器报错:SCRIPT5007: 无法获取属性“rowspan”的值: 对象为 null 或未定义
    身为一个产品经理应该了解自己的本职
    创意思维常用练习方法资料
    思维导图五个关键秘诀
    思维导图与超级记忆力之间的联系
    易让大脑变迟钝的九中习惯
    分享怎样快速阅读的5大方法
    思维导图运用的四个特征
  • 原文地址:https://www.cnblogs.com/Tony100K/p/11659884.html
Copyright © 2011-2022 走看看