zoukankan      html  css  js  c++  java
  • ZOJ 3794 Greedy Driver

    Greedy Driver

    Time Limit: 2000ms
    Memory Limit: 65536KB
    This problem will be judged on ZJU. Original ID: 3794
    64-bit integer IO format: %lld      Java class name: Main

    Edward is a truck driver of a big company. His daily work is driving a truck from one city to another. Recently he got a long distance driving work, so he may be needed to add fuel to his truck on the way. His boss gives him a fuel card, he can use the card anytime at any fuel station and add any amount of fuel. He does not spend any money when he uses the card. He noticed that there are some cities where he could sell fuel. The greedy driver Edward want to make some money while he doing this work. And this is his plan:

    There are N cities on his map and numbered from 1 to N, he need to drive from city 1 to city N to finish this task. Driving from one city to another need fuel cost too. There are some of the cities has fuel station, he could use his fuel card at these cities. Notice his truck has a fuel tank capacity C and it could not exceed the capacity when add fuel. At the beginning, he is at city 1 and he has a full tank.

    At some cities he could sell any amount of fuel he has, and the prices at each city maybe different. Since he does not want to be found, he sell the fuel at most once totally. Under the premise of driving to city N finally, he wants to make the maximal money.

    Input

    There are multiple test cases. For each test case:

    The first line contains three integer N (1 ≤ N ≤ 1000), M (1 ≤ M ≤ 100000), C(1 ≤ C ≤ 30000), N is the number of cities, M is the number of roads, please notice that the roads is single-way, and C is the fuel tank capacity.

    The after M lines describe the roads, each line has three integers A, B (1 ≤ A, BN), L (1 ≤ L ≤ 30000). That means the fuel cost from city A to city B is L.

    Then a single line contain one integer P (0 ≤ PN), it is the number of cities which has a fuel station.

    The after single line contains P integers, each integer pi (1 ≤ piN) is a city number means this city has a fuel station.

    Then a single line contain one integer Q (0 ≤ QN), it is the number of cities which he could sell fuel.

    Each of the after Q lines contains two integers qi (1 ≤ qiN), vi (1 ≤ vi ≤ 30000), means the price at city qi is vi. If he sell one unit of fuel, he will get vi money.

    There is a blank line between every two cases.

    Process to the end of input.

    Output

    One line for each test case. The maximal money he could make while doing this task, or -1 if he could not reach city N.

    Sample Input

    5 6 10
    1 2 4
    1 4 1
    4 3 1
    2 5 1
    4 5 2
    3 2 1
    1
    3
    1
    2 2
    

    Sample Output

    16
    

    Source

    Author

    LI, Huang
     
    解题:最短路,分别由起点和终点做两次最短路,遇到加油站,即置0!然后枚举可以卖油的站,看看在可以到达该点并且有足够的油到终点的情况下,最多可以卖多少油。
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int INF = 0x3f3f3f3f;
     4 const int maxn = 1010;
     5 struct arc {
     6     int to,w,flag,next;
     7     arc(int x = 0,int y = 0,int z = 0,int nxt = -1) {
     8         to = x;
     9         w = y;
    10         flag = z;
    11         next = nxt;
    12     }
    13 } e[1000010];
    14 int head[maxn],d[2][maxn],tot,n,m,C;
    15 bool oil[maxn],in[maxn];
    16 void add(int u,int v,int w) {
    17     e[tot] = arc(v,w,1,head[u]);
    18     head[u] = tot++;
    19     e[tot] = arc(u,w,0,head[v]);
    20     head[v] = tot++;
    21 }
    22 void spfa(int d[maxn],int S,int flag) {
    23     queue<int>q;
    24     q.push(S);
    25     d[S] = 0;
    26     while(!q.empty()) {
    27         int u = q.front();
    28         q.pop();
    29         in[u] = false;
    30         for(int i = head[u]; ~i; i = e[i].next) {
    31             if(e[i].flag^flag) continue;
    32             int tmp = d[u] + e[i].w;
    33             if(tmp <= C) {
    34                 if(oil[e[i].to]) tmp = 0;
    35                 if(d[e[i].to] > tmp) {
    36                     d[e[i].to] = tmp;
    37                     if(!in[e[i].to]) {
    38                         in[e[i].to] = true;
    39                         q.push(e[i].to);
    40                     }
    41                 }
    42             }
    43         }
    44     }
    45 }
    46 int main() {
    47     int u,v,w;
    48     while(~scanf("%d%d%d",&n,&m,&C)) {
    49         memset(head,-1,sizeof head);
    50         memset(oil,false,sizeof oil);
    51         memset(d,0x3f,sizeof d);
    52         for(int i = tot = 0; i < m; ++i) {
    53             scanf("%d%d%d",&u,&v,&w);
    54             if(w > C) continue;
    55             add(u,v,w);
    56         }
    57         scanf("%d",&m);
    58         while(m--) {
    59             scanf("%d",&u);
    60             oil[u] = true;
    61         }
    62         spfa(d[0],1,1);
    63         spfa(d[1],n,0);
    64         scanf("%d",&m);
    65         int ret = 0;
    66         while(m--) {
    67             scanf("%d%d",&u,&w);
    68             if(C - d[0][u] - d[1][u] > 0)
    69                 ret = max(ret,w*(C - d[0][u] - d[1][u]));
    70         }
    71         printf("%d
    ",d[0][n] == INF?-1:ret);
    72     }
    73     return 0;
    74 }
    View Code
  • 相关阅读:
    硬件的快速迭代开发
    DAC8775芯片的使用
    单片机引脚复用使用不当会导致bug
    单片机为32bit时运算中64bit运算中遇到的bug及其规避手段
    UDS文档的阅读
    DAC124S085芯片的使用
    LSD低边驱动芯片的特点
    小时候的玩具激光灯拆解
    飞思卡尔系列单片机的censorship的使用
    TypeScript学习小结
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4965141.html
Copyright © 2011-2022 走看看