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 这题显然要先把缩点做了. 然后我们就可以考虑如何处理走反向边的问题. 像我这样的 ...
随机推荐
- HTTP协议的状态码
对于Web编程人员来说,熟悉了解HTTP协议的状态码是很有必要的,很多时侯可能根据HTTP协议的状态码很快就能定位到错误信息!今天整理了一下所有HTTP状态码. HTTP状态码(HTTP Status ...
- Cocos2d-android (05) 渐变动画(颜色,淡入淡出。。。)
淡入淡出.颜色渐变及动作重复执行 import org.cocos2d.actions.base.CCRepeatForever; import org.cocos2d.actions.interva ...
- redhat Enterprise Linux Server release 7.2(Maipo) 安装redis-stat
项目需要在rh7.2安装redis-stat,各种编译不过.通过一步步跟踪编译错误日志发现时缺少各种开发库. 需要安装的库列表如下: zlib-devel openssl-devel readline ...
- 【C#】构造函数的特点
1.它的函数名与类名相同:2.它可以重载:3.不能指定返回类型,即使是void也不行:4.虽然在一般情况下,构造函数不被显式调用,而是在创建对象时自动被调用.但是并不是不能被显示调用.有些时候是一定要 ...
- QS之vcom
-2008 | -2002 | -93 | -87 choose VHDL 2008, 2002, 1993, or 1987 -explicit resolve ambiguous overload ...
- 两个实用的Python的装饰器
两个实用的Python的装饰器 超时函数 这个函数的作用在于可以给任意可能会hang住的函数添加超时功能,这个功能在编写外部API调用 .网络爬虫.数据库查询的时候特别有用 timeout装饰器的代码 ...
- 网络爬虫系统Heritrix的结构分析 (个人读书报告)
摘要 随着网络时代的日新月异,人们对搜索引擎,网页的内容,大数据处理等问题有了更多的要求.如何从海量的互联网信息中选取最符合要求的信息成为了新的热点.在这种情况下,网络爬虫框架heritrix出现 ...
- IDE Plug
IDE Plug 使用 cnpack提供的IDE External Wizard Management 管理插件.添加插件.删除插件 Cnpack D:\Program Files (x86)\CnP ...
- vim之vba文件
[vim之vba文件] Vimball 官方描述: The vimball plugin facilitates creating, extracting , and listing the cont ...
- HDU 4667 Building Fence
题意: 给n个圆和m个三角形,且保证互不相交,用一个篱笆把他们围起来,求最短的周长是多少. 做法:--水过... 把一个圆均匀的切割成500个点,然后求凸包. 注意:求完凸包,在求周长的时候记得要把圆 ...