POJ 3635 Full Tank? 【分层图/最短路dp】
任意门:http://poj.org/problem?id=3635
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 8388 | Accepted: 2734 |
Description
After going through the receipts from your car trip through Europe this summer, you realised that the gas prices varied between the cities you visited. Maybe you could have saved some money if you were a bit more clever about where you filled your fuel?
To help other tourists (and save money yourself next time), you want to write a program for finding the cheapest way to travel between cities, filling your tank on the way. We assume that all cars use one unit of fuel per unit of distance, and start with an empty gas tank.
Input
The first line of input gives 1 ≤ n ≤ 1000 and 0 ≤ m ≤ 10000, the number of cities and roads. Then follows a line with n integers 1 ≤ pi ≤ 100, where pi is the fuel price in the ith city. Then follow m lines with three integers 0 ≤ u, v < n and 1 ≤ d ≤ 100, telling that there is a road between u and v with length d. Then comes a line with the number 1 ≤ q ≤ 100, giving the number of queries, and q lines with three integers 1 ≤ c ≤ 100, s and e, where c is the fuel capacity of the vehicle, s is the starting city, and e is the goal.
Output
For each query, output the price of the cheapest trip from s to e using a car with the given capacity, or "impossible" if there is no way of getting from s to e with the given car.
Sample Input
5 5
10 10 20 12 13
0 1 9
0 2 8
1 2 1
1 3 11
2 3 7
2
10 0 3
20 1 4
Sample Output
170
impossible
Source
题意概括:
有 N 个城市 M 条道路(双向通行),每个城市都有一个加油站(每单位汽油售价分别为 pi ),道路每单位距离花费一单位汽油。求从起点到终点得最小花费(如果不能到达输出-1,因为小车车油箱有容量限制)。
解题思路:
终于还是把这题做了,也忘了是哪一次得集训遇到这道题,是一道好题,可惜当时自己做不出。
这道题正确的打开方式:分层图或者叫最短路dp(个人感觉分层图其实就是搞最短路dp,动态规划的思想)。
状态:dp[ i ][ j ] 到了第 i 个城市 还剩下 j 单位的油的最小花费。
状态转移分两种:
1、在当前城市加油(精妙之处在于每次只加 1 单位的油,以最少的油跑最远的地方,如果未来发现这里的油不划算庆幸没有多加而且加到刚刚好,如果未来发现这里的油划算,那就跑回来多加一点咯,因为我们这里是用一个优先队列来保存状态);
2、不加油,直接跑到下一个城市(当然要当前油箱的油可以行驶到下一个城市);
tip:
注意判重, 每种状态只入队一次。
AC code:
//poj 3635 最短路dp
//未优化输入
/*
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstring>
#define INF 0x3f3f3f3f
#define LL long long int
using namespace std;
const int MAX_M = 1e4+10;
const int MAX_N = 1e3+10;
const int MAX_K = 105;
struct date
{
int v, nxt, val;
}edge[MAX_M<<1]; struct node
{
int u, k, w;
bool operator < (const node& a)const{
return w > a.w;
}
node(int a=0, int b=0, int c=0):u(a),k(b),w(c){}
};
int N, M, tank, st, ed;
int coco[MAX_N];
int head[MAX_N], cnt;
int dis[MAX_N][MAX_K];
bool vis[MAX_N][MAX_K];
//priority_queue<node> Q; void init()
{
memset(head, -1, sizeof(head));
cnt = 1;
} void add(int from, int to, int weight)
{
edge[cnt].nxt = head[from];
edge[cnt].v = to;
edge[cnt].val = weight;
head[from] = cnt++;
} void Dijkstra(int s)
{
memset(dis, INF, sizeof(dis));
memset(vis, false, sizeof(vis));
priority_queue<node> Q;
node tp;
tp.u = s, tp.k = 0, dis[s][0] = tp.w = 0;
Q.push(tp);
while(!Q.empty()){
tp = Q.top();Q.pop();
vis[tp.u][tp.k] = true;
if(tp.u == ed){
printf("%d\n", tp.w);return;
} if(tp.k+1<=tank && !vis[tp.u][tp.k+1] && dis[tp.u][tp.k]+coco[tp.u] < dis[tp.u][tp.k+1]){
dis[tp.u][tp.k+1] = dis[tp.u][tp.k]+coco[tp.u];
Q.push(node(tp.u, tp.k+1, dis[tp.u][tp.k+1]));
} for(int i = head[tp.u]; i != -1; i = edge[i].nxt){
int v = edge[i].v, cost = edge[i].val;
if(tp.k >= cost && !vis[v][tp.k-cost] && dis[v][tp.k-cost] > tp.w){
dis[v][tp.k-cost] = tp.w;
Q.push(node(v, tp.k-cost, tp.w));
}
}
}
printf("impossible\n");
} int main()
{
int u, v, w;
scanf("%d%d", &N, &M);
init();
for(int i = 0; i < N; i++){
scanf("%d", &coco[i]);
}
for(int i = 1; i <= M; i++){
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d%d", &tank, &st, &ed);
Dijkstra(st);
}
return 0;
}
*/ //优化输入
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <queue>
#include <cstring>
#define INF 0x3f3f3f3f
#define LL long long int
using namespace std;
const int MAXN = ;
const int MAXM = 1e4+;
const int MAXK = ;
int N, M, st, ed, tank;
int p[MAXN]; ///每一站的油
int cost[MAXN][MAXK]; ///cost[i][j] 到达第i站还剩下j油的最小花费
int head[MAXN], cnt;
bool vis[MAXN][MAXK]; int read()
{
int f=, x=;char ch = getchar();
while(ch < '' || ch > '') {if(ch=='-')f=-;ch=getchar();}
while(ch >= '' && ch <= '') {x = x*+(ch-'');ch=getchar();}
x=x*f;return x;
}
struct node
{
int v, k, val;
bool operator < (const node& a)const{
return val > a.val;
}
node(int a=, int b=, int c=):v(a),k(b),val(c){};
}; struct date
{
int v, nxt, w;
}edge[MAXM<<]; void init()
{
memset(head, -, sizeof(head));
cnt = ;
}
void add(int from, int to, int weight)
{
edge[cnt].nxt = head[from];
edge[cnt].v = to;
edge[cnt].w = weight;
head[from] = cnt++;
} void Dijkstra(int S)
{
memset(cost, INF, sizeof(cost));
memset(vis, false, sizeof(vis));
node tp;
priority_queue<node> Q;
tp.v = S; tp.k = ; tp.val = ;
Q.push(tp);
cost[S][] = ;
while(!Q.empty()){
tp = Q.top(); Q.pop();
int fr = tp.v, oil = tp.k;
vis[fr][oil] = true;
if(fr == ed) {printf("%d\n", tp.val);return;} //因为是优先队列优化的所以到达终点值得第一个值就是最小值 if(oil+ <= tank && !vis[fr][oil+] && cost[fr][oil+] > cost[fr][oil]+p[fr]){ ///在当前站一滴一滴地加,最好的情况是加的少跑的远
cost[fr][oil+] = cost[fr][oil]+p[fr];
Q.push(node(fr, oil+, cost[fr][oil+]));
}
for(int i = head[fr]; i != -; i = edge[i].nxt){ ///跑到当前的油可以跑到的地方
int v = edge[i].v;
if(oil >= edge[i].w && !vis[v][oil-edge[i].w] && tp.val < cost[v][oil-edge[i].w]){
cost[v][oil-edge[i].w] = tp.val;
Q.push(node(v, oil-edge[i].w, tp.val));
}
}
}
printf("impossible\n");
} int main()
{
int u, v, w;
//scanf("%d%d", &N, &M);
init();
N = read(); M = read();
//printf("%d %d\n", N, M);
for(int i = ; i < N; i++) p[i] = read();
for(int i = ; i <= M; i++){
//scanf("%d%d%d", &u, &v, &w);
u = read(), v = read(), w = read();
add(u, v, w); ///无向图
add(v, u, w);
}
int T_case;
T_case = read();
while(T_case--){
tank = read(); st = read(); ed = read();
Dijkstra(st);
}
return ;
}
POJ 3635 Full Tank? 【分层图/最短路dp】的更多相关文章
- poj3635Full Tank?[分层图最短路]
Full Tank? Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7248 Accepted: 2338 Descri ...
- POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]
题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...
- POJ 1724 (分层图最短路)
### POJ 1724 题目链接 ### 题目大意: 给你 N 个点 ,M 条有向路,走每条路需要花费 C 元,这段路的长度为 L . 给你 K 元,问你能否从 1 走到 N 点且花费不超过 K 元 ...
- HDU 5669 线段树优化建图+分层图最短路
用线段树维护建图,即把用线段树把每个区间都标号了,Tree1中子节点有到达父节点的单向边,Tree2中父节点有到达子节点的单向边. 每次将源插入Tree1,汇插入Tree2,中间用临时节点相连.那么T ...
- BZOJ 2763 分层图最短路
突然发现我不会分层图最短路,写一发. 就是同层中用双向边相连,用单向边连下一层 #include <cstdio> #include <algorithm> #include ...
- 【网络流24题】 No.15 汽车加油行驶问题 (分层图最短路i)
[题意] 问题描述:给定一个 N*N 的方形网格,设其左上角为起点◎, 坐标为( 1, 1), X 轴向右为正, Y轴向下为正, 每个方格边长为 1, 如图所示. 一辆汽车从起点◎出发驶向右下角终点▲ ...
- 【网络流24题】 No.14 孤岛营救问题 (分层图最短路)
[题意] 1944 年,特种兵麦克接到国防部的命令,要求立即赶赴太平洋上的一个孤岛, 营救被敌军俘虏的大兵瑞恩. 瑞恩被关押在一个迷宫里, 迷宫地形复杂, 但幸好麦克得到了迷宫的地形图. 迷宫的外形是 ...
- BZOJ_2662_[BeiJing wc2012]冻结_分层图最短路
BZOJ_2662_[BeiJing wc2012]冻结_分层图最短路 Description “我要成为魔法少女!” “那么,以灵魂为代价,你希望得到什么?” “我要将有关魔法和奇迹的一切, ...
- BZOJ_1579_[Usaco2009 Feb]Revamping Trails 道路升级_分层图最短路
BZOJ_1579_[Usaco2009 Feb]Revamping Trails 道路升级_分层图最短路 Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M ...
随机推荐
- sublime Text 3 官方版 3114 注册码
—– BEGIN LICENSE —– Anthony Sansone Single User License EA7E-878563 28B9A648 42B99D8A F2E3E9E0 16DE0 ...
- (转)跟着老男孩一步步学习Shell高级编程实战
原文:http://oldboy.blog.51cto.com/2561410/1264627/ 跟着老男孩一步步学习Shell高级编程实战 原创作品,允许转载,转载时请务必以超链接形式标明文章 原 ...
- 【转】python平台libsvm安装
来源:http://blog.csdn.net/prom1201/article/details/51382358 网上有很多麻烦的在win64机器上安装libsvm的步骤,实际上只要在下面网站找到l ...
- 60分钟内从零起步驾驭Hive实战学习笔记(Ubuntu里安装mysql)
本博文的主要内容是: 1. Hive本质解析 2. Hive安装实战 3. 使用Hive操作搜索引擎数据实战 SparkSQL前身是Shark,Shark强烈依赖于Hive.Spark原来没有做SQL ...
- Js简易代码生成工具
代码 javascript:(function(){ document.body.innerHTML = '<textarea id="txtTemplate" style= ...
- 阿里云Tomcat运行shutdown.sh命令关闭时遇到的问题
1.安装完成jdk之后,然后安装tomcat. tomcat安装成功后,进入tomcat的安装目录,找到bin所在的目录. 使用./startup.sh,启动tomcat; 使用./shutdown. ...
- 使用pygame开发一个弹幕射击游戏(一)
本文作为开发过程记录用. 目前游戏画面: 下一个添加的功能:敌机可以进行射击. 弹幕类 from pygame.sprite import Sprite from pygame import tran ...
- bzoj 5314: [Jsoi2018]潜入行动
Description 外星人又双叒叕要攻打地球了,外星母舰已经向地球航行!这一次,JYY已经联系好了黄金舰队,打算联合所有JSO Ier抵御外星人的进攻.在黄金舰队就位之前,JYY打算事先了解外星人 ...
- 从Linux服务器下载文件到本地
通过安装xshell,连接服务器,通过以下命令可以方便的将服务器的文件下载到本地 #下载一个文件 sz filename #下载多个文件 sz filename1 filename2 #下载dir目录 ...
- MongoDB windows基础配置及集群搭建
由于公司业务的发展MSSQL已处于瓶颈.因为没钱买牛逼服务器只能靠软件来实现最大优化了.原来的系统架构如下图: