poj 3635 Full Tank? ( 图上dp )
题意:
已知每一个点的加油站的油价单位价格(即点权)。每条路的长度(边权)。
有q个询问。每一个询问包含起点s、终点e和油箱容量。
问从起点走到终点的最小花费。假设不可达输出impossible,否则输出最小的旅途费用。
算法:
事实上要分析状态= =感觉就像是dp。
最直接的想法是 每到一个点都加上要走到下一个点所须要的油量。可是走的路不同,究竟怎么处理加多少的问题呢?
因此想到分解状态。即拆点。每到一个点都+1单位的油量,然后把这个状态增加队列。另外假设如今油箱内的油足够达到下一点,
则更新状态,把新状态增加优先队列。
dp[i][j]表示到第i个城市剩余油量为j的花费。
简单的说。就是优先队列优化的最短路算法多了一维。
为了把全部可能的状态考虑到。
每到一个点仅仅有两种操作:1、加一单位的油 2、更新能走到的下一个点。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxm 10010
#define maxn 1010 using namespace std; struct Edge
{
int to,val,next;
}edge[maxm*2]; struct node
{
int id,cost,oil;
bool operator <(const node &b) const
{
return cost > b.cost;
}
};
bool vis[maxn][110];
int cnt,head[maxn],dp[maxn][110],ans,st,ed,cap,p[maxn];
priority_queue<node> q; void add(int x,int y,int z)
{
edge[cnt].to = y;
edge[cnt].val = z;
edge[cnt].next = head[x];
head[x] = cnt++;
} bool bfs()
{
memset(dp,0x3f,sizeof(dp));
memset(vis,0,sizeof(vis));
while(!q.empty())
q.pop();
int id,oil,cost;
ans = 0; dp[st][0] = 0;
node now,cur,next;
now.id = st;
now.cost = 0;
now.oil = 0;
q.push(now);
while(!q.empty())
{
cur = q.top();
q.pop();
id = cur.id,oil = cur.oil,cost = cur.cost;
if(id == ed)
{
ans = cost;
return true;
}
if(vis[id][oil]) continue;
vis[id][oil] = true;
if(oil < cap)
{
next.id = id;
next.cost = cost+p[id];
next.oil = oil+1;
if(dp[next.id][next.oil]>next.cost && !vis[next.id][next.oil])
{
dp[next.id][next.oil] = next.cost;
q.push(next);
}
}
for(int i=head[id];i!=-1;i = edge[i].next)
{
int u = edge[i].to;
int w = edge[i].val;
if(oil>=w && dp[u][oil-w]>cur.cost && !vis[u][oil-w])
{
next.oil = oil-w;
next.id = u;
next.cost = cost;
dp[u][next.oil] = next.cost;
q.push(next);
}
}
}
return false;
} int main()
{
int n,m,u,v,l,que;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(head,-1,sizeof(head));
cnt = 0; for(int i=0;i<n;i++)
scanf("%d",&p[i]);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&u,&v,&l);
add(u,v,l);
add(v,u,l);
}
scanf("%d",&que);
while(que--)
{
scanf("%d%d%d",&cap,&st,&ed);
if(bfs())
printf("%d\n",ans);
else printf("impossible\n");
}
}
return 0;
}
poj 3635 Full Tank? ( 图上dp )的更多相关文章
- POJ 3635 - Full Tank? - [最短路变形][手写二叉堆优化Dijkstra][配对堆优化Dijkstra]
题目链接:http://poj.org/problem?id=3635 题意题解等均参考:POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]. 一些口胡: ...
- zoj1232Adventure of Super Mario(图上dp)
题目连接: 啊哈哈.点我点我 思路: 这个题目是一个图上dp问题.先floyd预处理出图上全部点的最短路,可是在floyd的时候,把可以用神器的地方预处理出来,也就是转折点地方不能为城堡..预处理完成 ...
- POJ 3635 Full Tank? 【分层图/最短路dp】
任意门:http://poj.org/problem?id=3635 Full Tank? Time Limit: 1000MS Memory Limit: 65536K Total Submis ...
- poj 3635 Full Tank? ( bfs+dp思想 )
Full Tank? Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5857 Accepted: 1920 Descri ...
- POJ 3635 - Full Tank? - [最短路变形][优先队列优化Dijkstra]
题目链接:http://poj.org/problem?id=3635 Description After going through the receipts from your car trip ...
- 洛谷 P2656 (缩点 + DAG图上DP)
### 洛谷 P2656 题目链接 ### 题目大意: 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖 ...
- Codeforces 918D MADMAX 图上dp 组合游戏
题目链接 题意 给定一个 \(DAG\),每个边的权值为一个字母.两人初始各占据一个顶点(可以重合),轮流移动(沿着一条边从一个顶点移动到另一个顶点),要求每次边上的权值 \(\geq\) 上一次的权 ...
- [POJ 3635] Full Tank?
题目 Description 已知每个点的加油站的油价单价(即点权),每条路的长度(边权). 有q个询问,每个询问包括起点s.终点e和油箱容量c. 问从起点走到终点的最小花费.如果不可达输出impos ...
- [Luogu P3119] [USACO15JAN]草鉴定Grass Cownoisseur (缩点+图上DP)
题面 传送门:https://www.luogu.org/problemnew/show/P3119 Solution 这题显然要先把缩点做了. 然后我们就可以考虑如何处理走反向边的问题. 像我这样的 ...
随机推荐
- 全方位掌握 NSIS 的操作
NSIS 确实是一个不错的安装程序制作软件.新版本2.0a7真正实现了中文支持和支持 WinXP 的安装对话框.不过要用它实现漂亮的安装界面和完美的安装功能就必须好好的写脚本.而 NSIS 的脚本指令 ...
- Python单例模式研究
方法一 import threading class Singleton(object): __instance = None __lock = threading.Lock() # used t ...
- Beginner’s Guide(开始者向导)
This guide gives a basic introduction to nginx and describes some simple tasks that can be done with ...
- Arduino uno R3 ISP刷Rootloader for arduino pro mini
找了好久才发现的,好东西.介绍怎么使用uno对mini 刷Rootloader **SOLUTION** Reinstall the Arduino Pro Mini Bootloader using ...
- hadoop 异常及处理总结-01(小马哥-原创)
试验环境: 本地:MyEclipse 集群:Vmware 11+ 6台 Centos 6.5 Hadoop版本: 2.4.0(配置为自动HA) 试验背景: 在正常测试MapReduce(下简称MR)程 ...
- win7的centos虚拟机上搭建mysql5.6服务
1 安装包下载 mysql5.6下载地址: http://dev.mysql.com/downloads/mysql/ 这里选择linux版本: navicat11破解版的下载地址: http://d ...
- 轻松学习Linux之进程监视与管理
前后台进程转换-1 前后台进程转换-2 本文出自 "李晨光原创技术博客" 博客,谢绝转载!
- 第二百零一天 how can I坚持
sql要学的东西还很多,很简单的一个sql都不会写,还得请教别人,哎. 八千代.铜钱草,小叶元宝,绿萝.还有我的鱼,还有罗娜. 今天试用了一下三星,系统优化就是不行啊,掉电太快,想搞个小米5,还想买个 ...
- 思科ASA系列防火墙配置手册
使用console连接线登录方法 1.使用cisco的console连接线,连接设备的console口和计算机com口(笔记本用USB转COM口连接线)2.使用超级终端或secureCRT软件连接设备 ...
- Problems running django-admin
“command not found: django-admin”¶ django-admin should be on your system path if you installed Djang ...