zoukankan      html  css  js  c++  java
  • 最优贸易

    https://loj.ac/problem/2590

    题目描述

      阿龙要从1号节点到n号节点,每个节点对于一种商品有买入价和卖出价,同一节点买入价和卖出价相同,求在只执行一次买卖最多可以转多少钱。(可从夫经过节点)。

    思路

      首先我们考虑对于同一节点的买卖状态,我们只有3种:买,卖,不买不卖。那么显然,我们只需要对于每一个状态建一层图,在不买不卖和买之间连边,在买和卖之间连边,由于只会进行一次贸易,所以实际两种的状态我们分为三种(实际只有有水晶球和无水晶球),卖完之后无法再回到不买不卖这一层,这样就保证了只进行一次贸易。在这张图上跑一遍最短路,由于存在负权,我们只能跑spfa。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+10,M=1e6+20;
    int nxt[M],to[M],w[M],head[N],tot,n,m;
    int v[N],dis[N<<2];
    bool exist[N<<2];
    void add_edge(int x,int y,int v)
    {
        nxt[++tot]=head[x];
        head[x]=tot;
        to[tot]=y;
        w[tot]=v;
    }
    void build()
    {
        for(int i=1;i<=n;i++)
        {
            add_edge(i,i+n,v[i]);
            add_edge(i+n,i+n*2,-v[i]);
        }
    }
    void spfa()
    {
        memset(dis,0x3f,sizeof(dis));
        queue<int>q;
        dis[1]=0;q.push(1);exist[1]=1;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            exist[u]=0;
            for(int i=head[u];i;i=nxt[i])
            {
                int v=to[i];
                if(dis[v]>dis[u]+w[i])
                {
                    dis[v]=dis[u]+w[i];
                    if(!exist[v])
                    {
                        q.push(v);
                        exist[v]=1;
                    }
                }
            }
        }
    }
    int main() 
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%d",&v[i]);
        for(int i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            if(z==1)add_edge(x,y,0),add_edge(x+n,y+n,0),add_edge(x+n*2,y+n*2,0);
            else
            {
                add_edge(x,y,0);add_edge(x+n,y+n,0);add_edge(x+n*2,y+n*2,0);
                add_edge(y,x,0);add_edge(y+n,x+n,0);add_edge(y+n*2,x+n*2,0)    ;
            }    
        }
        build();
        spfa();
        int ans=0x3f3f3f3f;
        for(int i=0;i<3;i++)
            ans=min(ans,dis[i*n+n]);
        printf("%d",-ans);
        return 0;
    }
  • 相关阅读:
    Linux高并发内核优化-TougheRadius
    Zabbix 4.0 配置邮件报警功能
    Zabbix Agent 4.0 Windows 安装配置
    zabbix4.0前端个性化设置
    zabbix 4.0中文图形界面乱码问题
    Zabbix4.0系统告警“More than 75% used in the configuration cache”
    Zabbix4.0配置SNMP监控
    Zabbix4.0 SNMP安装
    Zabbix4.0添加cisco交换机基本监控步骤
    深入.NET框架
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11683232.html
Copyright © 2011-2022 走看看