• hdu1217Arbitrage--解题报告


    题意:套利,一个US币换取0.5 British pound,而1 British pound 换取10.0 French francs,同一时候 1 French franc buys 0.21 US dollar. 那么1 US dollar 能够换取 0.5 * 10.0 * 0.21 = 1.05 US dollars ,通过一系列换取得到1.05US币,那么就能够从中获取利润,问:给出一些货币,以及兑换率,问能否够从中获利

    题解:这里能够用最短路的方法解决:我们在边的结构体 加入兑换率,然后松弛过程中,不同于最短路的取小,我们要让它获利就要取大,那么我们在spfa之前的dis初始化的时候,我们就所有memset为0,dis[src] 源点就赋值 1.这样我们就能够依照上面的方式松弛操作,然后推断是否构成负环。。假设能够,那么意思就是dis 会越来越大,spfa 用cnt[i]表示 i 入队的次数,i的入队次数大于 顶点数就说明构成负环

    上马:

    #include <iostream>
    #include <map>
    #include <string>
    #include <cstring>
    #include <queue>
    
    using namespace std;
    
    #define MAX 35
    
    int N,M;
    
    struct Edge{
        int to,next;
        double rate;
    }edge[MAX*MAX];
    int head[MAX];
    
    void add(int u,int v,double rate,int i)
    {
        edge[i].to = v;
        edge[i].rate = rate;
        edge[i].next = head[u];
        head[u] = i;
    }
    
    double dis[MAX];
    int cnt[MAX];
    bool flag[MAX];
    bool spfa()
    {
        memset(flag,false,sizeof(flag));
        memset(cnt,0,sizeof(cnt));
        memset(dis,0,sizeof(dis));
    
        dis[0] = 1;
        flag[0] = true;
        cnt[0] = 1;
    
        queue<int> q;
        q.push(0);
    
        while(!q.empty())
        {
            int u = q.front(); q.pop();
            flag[u] = false;
            for(int i = head[u]; i != -1; i = edge[i].next)
            {
                int v = edge[i].to;
                double rate = edge[i].rate;
                if(dis[v] < dis[u]*rate){
                    dis[v] = dis[u]*rate;
                    if(!flag[v]){
                        q.push(v);
                        flag[v] = true;
                        cnt[v] ++;
                    }
                }
                if(cnt[v] > N) return true;
            }
        }
        return false;
    }
    
    int main()
    {
        string a,b;
        double rate;
        int cas = 1;
        while(cin >> N)
        {
            if(!N) break;
            map<string,int>m;
            for(int i = 0; i < N; i ++) {
                cin >> a;
                m[a] = i;
            }
            cin >> M;
            memset(head,-1,sizeof(head));
            for(int i = 0; i < M; i ++){
                cin >> a >> rate >> b;
                int u = (*m.find(a)).second;
                int v = (*m.find(b)).second;
                add(u,v,rate,i);
            }
    
            cout << "Case " << cas++ << ": ";
            if(spfa()) cout << "Yes" <<endl;
            else cout << "No" <<endl;
        }
        return 0;
    }

  • 相关阅读:
    java执行cmd程序
    修改linux 默认ssh的22端口
    docker入门(一)
    关键字:心跳网络、oracle rac 网络异常宕机、packet reassembles failed 、UDP error 转载大佬的一篇文章
    记录数据库心跳网络异常,导致数据库宕机--推荐使用OSWBB监控主机
    python项目一键导入所有安装包
    weblogic 中间件利用bsu 漏洞补丁升级
    weblogic 控制台密码输入5次错误被锁 / 密码忘记 修改密码的方法
    oracle数据泵工作学习记录
    简单粗暴的给Linux系统配置本地yum 源
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/3916888.html
Copyright © 2020-2023  润新知