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 ...
随机推荐
- Ubuntu 挂载ISO文件的方法
1.在终端中输入:sudo mkdir /media/iso 在/media下生成一个iso文件夹用来挂载iso文件2.然后输入:sudo mount -o loop /home/X/X/XXXX.i ...
- 基于visual Studio2013解决C语言竞赛题之1042字符串比较
题目 解决代码及点评 /********************************************************************** ...
- iOS开发 - 应用内打开第三方应用并传值
首先说下这个功能, 应该都有接触过. 比方,你下载了一个电子书,然后选择打开方式的时候,可能会看到你手机中已经安装的阅读类App. 或者,你的QQ收到了某个文件,你也能够选择本地的应用来打开. 那这种 ...
- windows 2003 域控制器(AD)的常规命令行操作以及修复
查询服务器的角色 Netdom query fsmo 强制升级操作主机角色(如果两台DC都无损,可以直接用图形模式传送,这里指的是一台DC出问题,另一台强制升级占用角色的情况) Ntdsutil Ro ...
- 国际化之MessageFormat与占位符
如果一个字符串文本中包含了多个与国际化相关的数据,可以使用MessageFormat类对这些数据进行批量处理. 例如: 在2016年1月9日的时候,一场台风导致了500间房屋的摧毁和¥1000000元 ...
- 终于懂了:TWinControl.DefaultHandler里的CallWindowProc(FDefWndProc)还挺有深意的,TButton对WM_PAINT消息的处理就是靠它来处理的(以前不明白为什么总是要调用inherited,其实就是没有明白TWinControl.DefaultHandler的真正用处)
我忽然发现:TButton既没有处理WM_PAINT,又没有Paint()或者PaintWindow(),那么它是什么时候被绘制的? Form1上放2个TButton,然后设置代码: procedur ...
- Delphi安装NT服务程序时(不出现提示信息)
如果我们不加上"/silent",那么Delphi在安装和卸载NT服务程序时候,都会出现一个提示信息,不希望出现这个提示信息,那么使用如下命令: 1,安装:“你的nt程序 /ins ...
- 慎得慌二u赫然共和任务i个屁
http://www.huihui.cn/share/8424421 http://www.huihui.cn/share/8424375 http://www.huihui.cn/share/842 ...
- UVA 529 Addition Chains(迭代搜索)
Addition Chains An addition chain for n is an integer sequence with the following four propertie ...
- VI01增强问题
函数'SD_SCD_ITEM_PRICING_DATA_GET',其实在增强中和交货相关的数据在这个函数中都可以取到,没有必要再从LIKP.LIPS等等中重新取数. include程序RV64A631 ...