ZOJ 3794 Greedy Driver
两次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 A, B (1 ≤ A, B ≤ 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的更多相关文章
- ZOJ 3794 Greedy Driver spfa
题意: 给定n个点,m条有向边,邮箱容量. 起点在1,终点在n,開始邮箱满油. 以下m行表示起点终点和这条边的耗油量(就是长度) 再以下给出一个数字m表示有P个加油站,能够免费加满油. 以下一行P个数 ...
- ZOJ Monthly, June 2014 月赛BCDEFGH题题解
比赛链接:点击打开链接 上来先搞了f.c,,然后发现状态不正确,一下午都是脑洞大开,, 无脑wa,无脑ce...一样的错犯2次.. 硬着头皮搞了几发,最后20分钟码了一下G,不知道为什么把1直接当成不 ...
- ZOJ Monthly, June 2014 解题报告
A.Another Recurrence Sequence problemId=5287">B.Gears 题目大意:有n个齿轮,一開始各自为一组.之后进行m次操作,包含下面4种类型: ...
- 深入linux kernel内核配置选项
============================================================================== 深入linux kernel内核配置选项 ...
- 重拾ZOJ 一周解题
ZOJ 2734 Exchange Cards 题目大意: 给定一个值N,以及一堆卡片,每种卡片有一个值value和数量number.求使用任意张卡片组成N的方式. 例如N = 10 ,cards(1 ...
- ZOJ 2475 Benny's Compiler(dfs判断有向图给定点有没有参与构成环)
B - Benny's Compiler Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu ...
- MongoDB Java Driver操作指南
MongoDB为Java提供了非常丰富的API操作,相比关系型数据库,这种NoSQL本身的数据也有点面向对象的意思,所以对于Java来说,Mongo的数据结构更加友好. MongoDB在今年做了一次重 ...
- c#操作MangoDB 之MangoDB CSharp Driver驱动详解
序言 MangoDB CSharp Driver是c#操作mongodb的官方驱动. 官方Api文档:http://api.mongodb.org/csharp/2.2/html/R_Project_ ...
- Java JDBC Thin Driver 连接 Oracle 三种方法说明(转载)
一.JDBC 连接Oracle 说明 JDBC 的应用连接Oracle 遇到问题,错误如下: ORA-12505,TNS:listener does not currently know of SID ...
随机推荐
- List接口实现类-ArrayList、Vector、LinkedList集合深入学习以及源代码解析
学习List接口实现类 ArrayList Vector LinkedList List接口的实现类中最经常使用最重要的就是这三个:ArrayList.Vector.LinkedList. JDK ...
- Android漫游记(4)---.so文件动态调试一例
Android平台的动态调试一直以来是个困扰我等Coder的头疼问题,特别是对于本地的动态调试支持.能够说是"弱智"级别的,不知道Google的新版NDK和新出的Android S ...
- Swift - 单例模式的实现
过去Swift要实现单例,无非是这三种方式:全局变量,内部变量和dispatch_once方式.但都略显繁琐. 后来从1.2版本起,Swift中添加了如 static let 和 static var ...
- 《UNIX环境高级编程》笔记--sigaction函数
sigaction函数的功能是检查或修改指定信号相关联的处理动作,此函数取代UNIX早期版本使用的signal函数. #include<signal.h> int sigaction(in ...
- Microsoft Visual C++运行库合集下载(静默安装)
Microsoft Visual C++运行库合集下载 CN启示录2013-06-02上传 Microsoft Visual C++运行库合集由国外网友McRip制作,包含了VC2005.VC20 ...
- 微信公 众平台开发,用于个人技术交流,有兴趣的加QQ群432921500
微信公 众平台开发,用于个人技术交流,有兴趣的加QQ群432921500
- 【学习opencv第七篇】图像的阈值化
图像阈值化的基本思想是,给定一个数组和一个阈值,然后根据数组中每个元素是低于还是高于阈值而进行一些处理. cvThreshold()函数如下: double cvThreshold( CvArr* s ...
- 以&运行在后台的程序,关闭terminal后,相应进进程自动关闭
以&运行在后台的程序,关闭terminal后,相应进进程自动关闭
- 选择屏幕中的下拉框和dialog中下拉框设计
REPORT YTEST014. PARAMETERS: auart LIKE vapma-auart AS LISTBOX VISIBLE LENGTH 6. AT SELECTION-SC ...
- 【ASP.NET Web API教程】5.2 发送HTML表单数据:URL编码的表单数据
原文:[ASP.NET Web API教程]5.2 发送HTML表单数据:URL编码的表单数据 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...