zoukankan      html  css  js  c++  java
  • POJ 1860 Currency Exchange(最短路&spfa正权回路)题解

    题意:n种钱,m种汇率转换,若ab汇率p,手续费q,则b=(a-q)*p,你有第s种钱v数量,问你能不能通过转化让你的s种钱变多?

    思路:因为过程中可能有负权值,用spfa。求是否有正权回路,dis[s]是否增加。把dis初始化为0,然后转化,如果能增大就更新。每次都判断一下dis[s]。

    参考:最快最好用的——spfa算法

    代码:

    #include<cstdio>
    #include<set>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int maxn = 100+5;
    const int INF = 0x3f3f3f3f;
    struct Edge{
        int v;
        double cost,dec;
        Edge(int _v = 0,double _c = 0,double _d = 0):v(_v),cost(_c),dec(_d){}
    };
    vector<Edge> G[maxn];
    bool vis[maxn]; //在队列标志
    //int cnt[maxn];  //每个点入队列次数
    double dis[maxn];
    bool spfa(int start,double V,int n){
        memset(vis,false,sizeof(vis));
        for(int i = 1;i <= n;i++) dis[i] = 0;
        vis[start] = true;
        dis[start] = V;
        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 < G[u].size();i++){
                int v = G[u][i].v;
                double c = G[u][i].cost;
                double d = G[u][i].dec;
                if(dis[v] < (dis[u] - d)*c){
                    dis[v] = (dis[u] - d)*c;
                    if(!vis[v]){
                        q.push(v);
                        vis[v] = true;
                        /*if(++cnt[v] > n)
                            return false;*/
                    }
                }
                if(dis[start] > V)
                    return true;
            }
        }
        return false;
    }
    void addEdge(int u,int v,double cost,double dec){
        G[u].push_back(Edge(v,cost,dec));
    }
    int main(){
        int n,m,s;
        double V;
        while(scanf("%d%d%d%lf",&n,&m,&s,&V) != EOF){
            for(int i = 1;i <= n;i++) G[i].clear();
            for(int i = 0;i < m;i++){
                int u,v;
                double c,d;
                scanf("%d%d%lf%lf",&u,&v,&c,&d);
                addEdge(u,v,c,d);
                scanf("%lf%lf",&c,&d);
                addEdge(v,u,c,d);
            }
            bool flag = spfa(s,V,n);
            if(flag) printf("YES
    ");
            else printf("NO
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    [BJOI2019] 光线
    C# 从零开始写 SharpDx 应用 笔刷
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    BAT 脚本判断当前系统是 x86 还是 x64 系统
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    win2d 通过 CanvasActiveLayer 画出透明度和裁剪
    PowerShell 拿到显卡信息
    PowerShell 拿到显卡信息
    win10 uwp 如何使用DataTemplate
    win10 uwp 如何使用DataTemplate
  • 原文地址:https://www.cnblogs.com/KirinSB/p/9408731.html
Copyright © 2011-2022 走看看