两次SPFA

第一关找:从1没有出发点到另一个点的多少是留给油箱

把边反过来再找一遍:重每一个点到终点最少须要多少油

Greedy Driver


Time Limit: 2 Seconds      Memory Limit: 65536 KB


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 AB (1 ≤ AB ≤ N), 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 ≤ P ≤ N), it is the number of cities which has a fuel station.

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

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

Each of the after Q lines contains two integers qi (1 ≤ qi ≤ N), 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

Author: LI, Huang

Source: ZOJ Monthly, June 2014

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue> using namespace std; const int maxn=110000;
const int INF=0x3f3f3f3f; struct Edge
{
int to,next,cost;
}edge[maxn],edge2[maxn]; int Adj[maxn/100],Adj2[maxn/100],Size,Size2;
int fuel[maxn/100],price[maxn/100],n,m,c,p,q; void init()
{
Size=Size2=0;
memset(Adj,-1,sizeof(Adj));
memset(Adj2,-1,sizeof(Adj2));
memset(fuel,0,sizeof(fuel));
memset(price,0,sizeof(price));
} void Add_Edge(int u,int v,int w)
{
edge[Size].next=Adj[u];
edge[Size].to=v;
edge[Size].cost=w;
Adj[u]=Size++;
} void Add_Edge2(int u,int v,int w)
{
edge2[Size2].next=Adj2[u];
edge2[Size2].to=v;
edge2[Size2].cost=w;
Adj2[u]=Size2++;
} int dmax[maxn/100],cq[maxn],dmin[maxn/100];
bool inq[maxn/100]; bool spfa_find_max()
{
memset(dmax,-1,sizeof(dmax));
memset(cq,0,sizeof(cq));
memset(inq,false,sizeof(inq));
dmax[1]=c;
queue<int> q;
inq[1]=true,cq[1]=1; q.push(1); while(!q.empty())
{
int u=q.front();q.pop();
for(int i=Adj[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(dmax[u]-edge[i].cost<0) continue;
if(dmax[v]<dmax[u]-edge[i].cost)
{
if(fuel[v]) dmax[v]=c;
else dmax[v]=dmax[u]-edge[i].cost;
if(inq[v]==false)
{
inq[v]=true;
cq[v]++;
if(cq[v]>=n) return false;
q.push(v);
}
}
}
inq[u]=false;
}
return true;
} bool spfa_find_min()
{
memset(dmin,63,sizeof(dmin));
memset(inq,false,sizeof(inq));
memset(cq,0,sizeof(cq));
dmin[n]=0;
queue<int> q;
q.push(n);
inq[n]=true,cq[n]=1; while(!q.empty())
{
int u=q.front(); q.pop(); for(int i=Adj2[u];~i;i=edge2[i].next)
{
int v=edge2[i].to;
if(dmin[u]+edge2[i].cost>c) continue;
if(dmin[v]>dmin[u]+edge2[i].cost)
{
if(fuel[v]) dmin[v]=0;
else
{
dmin[v]=dmin[u]+edge2[i].cost;
}
if(inq[v]==false)
{
inq[v]=true;
cq[v]++;
if(cq[v]>=n) return false;
q.push(v);
}
}
}
inq[u]=false;
}
return true;
} int main()
{
while(scanf("%d%d%d",&n,&m,&c)!=EOF)
{
init();
for(int i=0;i<m;i++)
{
int u,v,x;
scanf("%d%d%d",&u,&v,&x);
Add_Edge(u,v,x);
Add_Edge2(v,u,x);
}
scanf("%d",&p);
for(int i=0;i<p;i++)
{
int x; scanf("%d",&x);
fuel[x]=1;
}
scanf("%d",&q);
for(int i=0;i<q;i++)
{
int x,y; scanf("%d%d",&x,&y);
price[x]=y;
}
spfa_find_max();///油箱里最多剩下多少油
spfa_find_min();///到终点最少须要多少油
if(dmax[n]==-1||dmin[1]==INF) puts("-1");
else
{
int ans=0;
for(int i=1;i<=n;i++)
{
if(price[i]&&dmax[i]!=-1&&dmin[i]!=INF)
{
ans=max(ans,price[i]*(dmax[i]-dmin[i]));
}
}
printf("%d\n",ans);
}
}
return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

ZOJ 3794 Greedy Driver的更多相关文章

  1. ZOJ 3794 Greedy Driver spfa

    题意: 给定n个点,m条有向边,邮箱容量. 起点在1,终点在n,開始邮箱满油. 以下m行表示起点终点和这条边的耗油量(就是长度) 再以下给出一个数字m表示有P个加油站,能够免费加满油. 以下一行P个数 ...

  2. ZOJ Monthly, June 2014 月赛BCDEFGH题题解

    比赛链接:点击打开链接 上来先搞了f.c,,然后发现状态不正确,一下午都是脑洞大开,, 无脑wa,无脑ce...一样的错犯2次.. 硬着头皮搞了几发,最后20分钟码了一下G,不知道为什么把1直接当成不 ...

  3. ZOJ Monthly, June 2014 解题报告

    A.Another Recurrence Sequence problemId=5287">B.Gears 题目大意:有n个齿轮,一開始各自为一组.之后进行m次操作,包含下面4种类型: ...

  4. 深入linux kernel内核配置选项

    ============================================================================== 深入linux kernel内核配置选项 ...

  5. 重拾ZOJ 一周解题

    ZOJ 2734 Exchange Cards 题目大意: 给定一个值N,以及一堆卡片,每种卡片有一个值value和数量number.求使用任意张卡片组成N的方式. 例如N = 10 ,cards(1 ...

  6. ZOJ 2475 Benny's Compiler(dfs判断有向图给定点有没有参与构成环)

    B - Benny's Compiler Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu ...

  7. MongoDB Java Driver操作指南

    MongoDB为Java提供了非常丰富的API操作,相比关系型数据库,这种NoSQL本身的数据也有点面向对象的意思,所以对于Java来说,Mongo的数据结构更加友好. MongoDB在今年做了一次重 ...

  8. c#操作MangoDB 之MangoDB CSharp Driver驱动详解

    序言 MangoDB CSharp Driver是c#操作mongodb的官方驱动. 官方Api文档:http://api.mongodb.org/csharp/2.2/html/R_Project_ ...

  9. Java JDBC Thin Driver 连接 Oracle 三种方法说明(转载)

    一.JDBC 连接Oracle 说明 JDBC 的应用连接Oracle 遇到问题,错误如下: ORA-12505,TNS:listener does not currently know of SID ...

随机推荐

  1. maven项目部署到Repository(Nexus)

    目录[-] (一)下载并安装Nexus (二)配置Nexus Repository 说明: (三)在项目中配置Nexus Repository的信息 (四)发布到Nexus Repository 本文 ...

  2. hihocoder1302 最长回文子串

    hihocoder1302 最长回文子串 先贴代码 所有的上面的提示已经交代的好清楚了…… #include <iostream> #include <cstring> #in ...

  3. clearcase常用命令

    版本控制工具学习 http://www.itpxpj.com/course.do?method=getAllCourseInFront&classTypeId=21 1.[ClearCase] ...

  4. 快速安装多系统(xp与win7)

    具体方法: 1.利用pe安装xp系统 2.xp下,空出一个分区,用于安装win7 3.进入pe下,安装win7系统到空出的分区 4.win7正常启动后,会覆盖原来xp的启动方式 5.再次进入pe,利用 ...

  5. hdu 4812 D Tree(树的点分治)

    D Tree Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total ...

  6. 利用Android属性动画实现Banner的原理与实践

    事实上在Android刚推出属性动画的时候.就想利用它来设计一个Banner控件,一直没什么时间尝试. 在当时看我们应用中的Banner,使用计时器来控制自己主动播放,设置一个非常大的数,利用余数原理 ...

  7. JavaScript的原型继承

    JavaScript是一门面向对象的语言.在JavaScript中有一句很经典的话,万物皆对象.既然是面向对象的,那就有面向对象的三大特征:封装.继承.多态.这里讲的是JavaScript的继承,其他 ...

  8. TDD测试驱动的javascript开发(3) ------ javascript的继承

    说起面向对象,人们就会想到继承,常见的继承分为2种:接口继承和实现继承.接口继承只继承方法签名,实现继承则继承实际的方法. 由于函数没有签名,在ECMAScript中无法实现接口继承,只支持实现继承. ...

  9. 关于iOS7以后版本号企业公布问题

    大家都知道,苹果在公布7.1以后,不打个招呼就把企业公布方式给换掉了(谴责一下~) 曾经普通server+web页面+ipa+plist就能够搞定,如今已经不行了. 关于如今企业公布教程网上贴出来了非 ...

  10. Android学习笔记(十三)——碎片(一)

    碎片 碎片可看作第二种形式的活动,能够创建碎片来包括视图. 碎片总是嵌入在活动中,一般有两种常见形式: 1.碎片A和碎片B分别处于不同的活动中,当选择碎片A中的某一项时,触发碎片B启动: 2.碎片A和 ...