ZOJ_3794_Greedy Driver(单源最短路)
来源:互联网 发布:中国东盟贸易数据 编辑:程序博客网 时间:2024/05/16 02:16
题型:图论
题意:
n个city,m条边。一个司机从1点开车到n点,每条边都有耗油量w,有一些点是加油站,有一些点是可以卖油点且每个卖油点都有各自的卖油单价val。司机遇到加油站是就可以把油加满,中途只能卖一次油。问司机从1点出发至n点后最多可以赚多少油钱。
分析:
直观上,每条路径上安排几个卖油点或者是几个加油站是做不到的。转而想,既然中途只能买一次油,那么只需枚举卖油点即可。
当到达卖油点 i 时,设从起点到该卖油点所剩的最大油量为Left,从该卖油点抵达终点所需的最少耗油量为Cost,则有
Sell = Left - Cost
要追求的是最大的Sell量,所以需要Left尽量大而cost尽量小。
对于Left的求解,可以想象成为从起点到各个点的最短路径的变形,求到每个点的油最大剩余量,起点油量为c,遇到加油站时,剩余油量变为c。
对于Cost的求解,可以想象成为从终点到各个点的最短路径的变形,求终点到各个点的最少耗油量,终点耗油量为0,遇到加油站耗油量为0。
代码:
#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<queue>#define mt(a,b) sizeof(a,b,sizeof(a));#define M 1234#define INF 0x3f3f3f3fusing namespace std;int n,m,c;struct G { struct E { int u; int v; int w; int next; } e[M*M]; int le,head[M]; void init() { le = 0; memset(head,-1,sizeof(head)); } void add(int u,int v,int w) { e[le].u = u; e[le].v = v; e[le].w = w; e[le].next = head[u]; head[u] = le++; }} g1,g2; //原图和反图int dis1[M],dis2[M];bool used[M];bool station[M],sell[M];void SPFA_from_start() { queue<int> q; q.push(1); used[1] = true; dis1[1] = c; while(!q.empty()) { int u = q.front(); q.pop(); used[u] = false; for(int i=g1.head[u]; i!=-1; i=g1.e[i].next) { int v = g1.e[i].v; int w = g1.e[i].w; if(dis1[u] < w) continue; if(station[v]) { if(dis1[v]<c) { dis1[v] = c; if(!used[v]) { used[v] = true; q.push(v); } } } else { if(dis1[v] < dis1[u] - w) { dis1[v] = dis1[u] - w; if(!used[v]) { used[v] = true; q.push(v); } } } } }}void SPFA_from_end() { queue<int> q; q.push(n); used[n] = true; dis2[n] = 0; while(!q.empty()) { int u = q.front(); q.pop(); used[u] = false; for(int i=g2.head[u]; i!=-1; i=g2.e[i].next) { int v = g2.e[i].v; int w = g2.e[i].w; if(dis2[u]+w>c)continue; if(station[v]) { if(dis2[v]>0) { dis2[v]=0; if(!used[v]) { used[v]=true; q.push(v); } } } else { if(dis2[v]>dis2[u]+w) { dis2[v]=dis2[u]+w; if(!used[v]) { used[v]=true; q.push(v); } } } } }}int main() { int P,Q; while(~scanf("%d%d%d",&n,&m,&c)) { g1.init(); g2.init(); int u,v,w; for(int i=0; i<m; i++) { scanf("%d%d%d",&u,&v,&w); g1.add(u,v,w); g2.add(v,u,w); } memset(station,false,sizeof(station)); memset(sell,false,sizeof(sell)); scanf("%d",&P); int tmp; for(int i=0; i<P; i++) { scanf("%d",&tmp); station[tmp] = true; } memset(dis1,-1,sizeof(dis1)); for(int i=0; i<=M; i++) { dis2[i] = INF; } memset(used,false,sizeof(used)); SPFA_from_start(); memset(used,false,sizeof(used)); SPFA_from_end(); scanf("%d",&Q); int id,value; int ans = 0; while(Q--){ scanf("%d%d",&id,&value); if(dis1[id]>=0&&dis2[id]<=c) { ans=max(ans,(dis1[id]-dis2[id])*value); } } if(dis1[n]<0)ans=-1; printf("%d\n",ans); } return 0;}/*5 6 101 2 41 4 14 3 12 5 14 5 23 2 11312 2*/
0 0
- ZOJ_3794_Greedy Driver(单源最短路)
- zoj 3794 Greedy Driver(最短路)
- ZOJ 3794 Greedy Driver 最短路
- ZOJ - 3794 Greedy Driver 最短路
- 单源最短路
- 最短路之单源最短路
- Driver
- driver
- 单源最短路算法HDU 2544 ( 最短路 )
- HDU 2544 - 最短路(单源最短路)
- HDU 2544 最短路 (单源最短路)
- hdu_3788_单源最短路
- 单源最短路dijkstra算法
- 单源最短路(Bellman_Ford)
- poj 3013 单源最短路
- 单源最短路问题
- 单源最短路模板
- 单源最短路算法总结
- 【唇枪舌战】时间过半你的网店经营业绩目标过半了吗?
- KindEditor html 在线编译器
- JQuery学习记录
- vim打造IDE
- 中断号和芯片中断引脚的关系
- ZOJ_3794_Greedy Driver(单源最短路)
- Java Longest Palindromic Substring(最长回文字符串)
- Linux学习笔记1:基础知识
- HDU 4325 Vampire Numbers 打表
- Linux学习笔记2:用户管理、目录结构、常用命令
- Python科学计算函数库介绍
- c++ socket编程
- 第20条:类层次优于标签
- 面向对象设计原则