• P1938 [USACO09NOV]Job Hunt S


    P1938 [USACO09NOV]Job Hunt S

    题目描述

    Bessie is running out of money and is searching for jobs. Farmer John knows this and wants the cows to travel around so he has imposed a rule that his cows can only make D (1 <= D <= 1,000) dollars in a city before they must work in another city. Bessie can, however, return to a city after working elsewhere for a while and again earn the D dollars maximum in that city. There is no limit on the number of times Bessie can do this.

    Bessie's world comprises P (1 <= P <= 150) one-way paths connecting C (2 <= C <= 220) cities conveniently numbered 1..C. Bessie is currently in city S (1 <= S <= C). Path i runs one-way from city A_i to city B_i (1 <= A_i <= C; 1 <= B_i <= C) and costs nothing to traverse.

    To help Bessie, Farmer John will give her access to his private jet service. This service features F (1 <= F <= 350) routes, each of which is a one way flight from one city J_i to a another K_i (1 <= J_i <= C; 1 <= K_i <= C) and which costs T_i (1 <= T_i <= 50,000) dollars. Bessie can pay for the tickets from future earnings if she doesn't have the cash on hand.

    Bessie can opt to retire whenever and wherever she wants. Given an unlimited amount of time, what is the most money that Bessie can make presuming she can make the full D dollars in each city she can travel to? Print -1 if there is no limit to this amount.

    奶牛们正在找工作。农场主约翰知道后,鼓励奶牛们四处碰碰运气。而且他还加了一条要求:一头牛在一个城市最多只能赚D(1≤D≤1000)美元,然后它必须到另一座城市工作。当然,它可以在别处工作一阵子后又回到原来的城市再最多赚D美元。而且这样的往返次数没有限制。

    城市间有P(1≤P≤150)条单向路径连接,共有C(2≤C≤220)座城市,编号从1到C。奶牛贝茜当前处在城市S(1≤S≤C)。路径i从城市A_i到城市B_i(1≤A_i≤C,1≤B_i≤C),在路径上行走不用任何花费。

    为了帮助贝茜,约翰让它使用他的私人飞机服务。这项服务有F条(1≤F≤350)单向航线,每条航线是从城市J_i飞到另一座城市K_i(1≤J_i≤C,1≤K_i≤C),费用是T_i(1≤T_i≤50000)美元。如果贝茜手中没有现钱,可以用以后赚的钱来付机票钱。

    贝茜可以选择在任何时候,在任何城市退休。如果在工作时间上不做限制,贝茜总共可以赚多少钱呢?如果赚的钱也不会出现限制,就输出-1。

    输入格式

    第一行:5个用空格分开的整数D,P,C,F,S。

    第2到第P+1行:第i+1行包含2个用空格分开的整数,表示一条从城市A_i到城市B_i的单向路径。

    接下来F行,每行3个用空格分开的整数,表示一条从城市J_i到城市K_i的单向航线,费用是T_i。

    输出格式

    一个整数,在上述规则下最多可以赚到的钱数。

    输入输出样例

    输入 #1

    100 3 5 2 1
    1 5
    2 3
    1 4
    5 2 150
    2 5 120

    输出 #1

    250

    说明/提示

    This world has five cities, three paths and two jet routes. Bessie starts out in city 1, and she can only make 100 dollars in each city before moving on.

    Bessie can travel from city 1 to city 5 to city 2 to city 3, and make a total of 4*100 - 150 = 250 dollars.

    Source: USACO 2009 November Silver

    这个世界上有五个城市,三条单向路径和两条单向航线。贝茜从一号城市开始她的旅行,她在离开一个城市前最多只能在这个城市赚100美元。

    贝茜可以通过从一号城市-->五号城市-->二号城市-->三号城市的旅行赚到4*100-150=250美元。

    (注:在四个城市各赚100美元,从五号城市飞到二号城市花掉150美元)

    分析

      呵呵呵呵,这到题的题解隔了好几天才写,都快忘了。

      这道题把点权当作边权,因为走没有任何花费,但是做飞机有话费,所以两个城市之间如果有道路,那就不再建一条航线边,然后初始化的时候注意dis[s] = d;不能初始化为0,以为走出这个城市的时候已经赚了d元,也就是一开始就有d元钱。就跑spfa就可以了,还有就是判环。

    Code

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 600;
    int d,p,c,f,s;
    int x,y,z;
    int ed[N][N];
    int tot[N],j;
    int dis[N],head[N],cnt;
    bool vis[N];
    queue<int>q;
    
    struct edge{
        int to;
        int ne;
        int w;
    }e[N];
    
    void add(int u,int v,int w){
        e[++cnt].to = v;
        e[cnt].w = w;
        e[cnt].ne = head[u];
        head[u] = cnt;
    }
    
    void spfa(){
        for(int i=1;i<=c;i++)dis[s] = -1e9;
        dis[s] = d;
        vis[s] = 1;
        q.push(s);
        while(!q.empty()){
            int f = q.front();
            vis[f] = 0;
            q.pop();
            for(int i = head[f]; i ;i = e[i].ne){
                int v = e[i].to;
                if(dis[v]<dis[f]+e[i].w){
                    tot[v]++;
                    if(tot[v]>c){
                        printf("-1
    ");
                        j=1;
                        return ;
                    }
                    dis[v] = dis[f]+e[i].w;
                    if(!vis[v]){
                        q.push(v);
                        vis[v]=1;
                    }
                }
            }
        }
    }
    
    int main(){
        scanf("%d%d%d%d%d",&d,&p,&c,&f,&s);
        for(int i = 1;i <= p;i++){
            scanf("%d%d",&x,&y);
            ed[x][y]=d;
            add(x,y,d);
        }
        for(int i = 1;i <= f;i++){
            scanf("%d%d%d",&x,&y,&z);
            if(!ed[x][y])
                add(x,y,d-z);
        }
        spfa();
        if(j == 1){
            printf("-1
    ");
            return 0;
        }
        int ans = -1e9;
        for(int i = 1;i<=c;i++){
            ans = max(ans,dis[i]);
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    Vmware克隆虚拟机后网卡eth0变eth1解决
    iptables详解
    Python小白的发展之路之Python基础(二)【字符串、列表、集合、文件操作】
    ubuntu下的apt-get内网本地源的搭建
    Python小白的发展之路之Python基础(一)
    qtp录制---点击Activescreen时提示“一个或多个ActiveX控件无法显示”
    qtp录制ie,提示“是否只查看安全传送的网页内容”
    qtp录制ie崩溃
    bug的记录方式
    测试计划和测试方案的区别
  • 原文地址:https://www.cnblogs.com/LightyaChoo/p/13251871.html
Copyright © 2020-2023  润新知