zoukankan      html  css  js  c++  java
  • 题解 P4874 【[USACO14DEC] Piggyback_Silver 背负式运输(银)】

    此题其实比较水的。。。

    首先我们来分析题目,我们假设,贝茜和艾尔西在i点相遇后贝西开始扛艾尔西,那么代价为多少呢?

    显然,代价=贝茜到i点的最小代价+艾尔西到i点的最小代价+贝茜和艾尔西一起到n点的最小代价。

    我们分开解决,首先贝茜到i点的最小代价=走的最少步数*b,而走的步数,我们跑一遍以spfa(1)就可以轻松求出来了!

    同理。艾尔西,我们跑spfa(2)就可以求出,而共同走到n,我们跑spfa(n)即可~

    意思是,我们先跑三遍spfa:spfa(1),spfa(2),spfa(n),分别求出1到i的步数,设为dis[i][1].2到i的最小步数,设为dis[i][2],n到i的最小步数,设为dis[i][3].

    那么我们就可以知道,在i点集合后再背负到n的代价为:dis[i][1]b+dis[i][2]e+dis[i][3]*p;

    所以我们只需要O(n)枚举集合点i,然后O(1)计算取最小就好了

    至于如果p>b+e怎么办,其实此时最优方案就是各走各的,就相当于在n点集合。

    以下为代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long//三年oi一场空,不开long long见祖宗.
    const int N=4e4+1,inf=1e17;
    struct node{
        int v,nex;
    }t[N<<1];
    int len,las[N];
    int dis[N][4],n;
    bool vis[N];
    inline void add(int u,int v){//加双向边
        len++;
        t[len].v=v;
        t[len].nex=las[u],las[u]=len;
        len++;
        t[len].v=u;
        t[len].nex=las[v],las[v]=len;
    }
    inline void spfa(int z,int y){//spfa,当然,它死了...
        queue<int>s;
        s.push(z);
        dis[z][y]=0;
        while(!s.empty()){
            int x=s.front();
            s.pop();
            vis[x]=0;
            for(int i=las[x];i;i=t[i].nex){
                int v=t[i].v;
                if(dis[v][y]>dis[x][y]+1){
                    dis[v][y]=dis[x][y]+1;
                    if(!vis[v]){
                        vis[v]=1;
                        s.push(v);
                    }
                }
            }
        }
    }
    main(){
        memset(dis,0x3f3f,sizeof(dis));//初始化
        int b,e,p,m;
        scanf("%lld%lld%lld%lld%lld",&b,&e,&p,&n,&m);
        for(int i=1;i<=m;++i){
            int u,v;
            scanf("%lld%lld",&u,&v);
            add(u,v);
        }
        spfa(1,1),spfa(2,2),spfa(n,3);//跑spfa,因为空间只需要3*n,所以用此方法。。。
        long long ans=inf;
        for(int i=1;i<=n;++i){//枚举集合点
            long long now=1LL*b*dis[i][1]+1LL*e*dis[i][2]+1LL*p*dis[i][3];//计算最小代价
            ans=min(ans,now);
        }
        printf("%lld",ans);
        return 0;
    }
  • 相关阅读:
    Delphi TWebBrowser[11] 读写html代码
    Nginx 配置反向代理
    清除git中缓存的凭证(用户名及密码)
    python 摄像头
    a 链接控制打开新窗口 无地址栏
    树形多级菜单数据源嵌套结构与扁平结构互转
    使用 git 的正确姿势
    JavaScript this
    JavaScript Scope Chain
    JavaScript Scope Context
  • 原文地址:https://www.cnblogs.com/ThinkofBlank/p/10166922.html
Copyright © 2011-2022 走看看