题目大概说,一辆带有一个容量有限的油箱的车子在一张图上行驶,每行驶一单位长度消耗一单位油,图上的每个点都可以加油,不过都有各自的单位费用,问从起点驾驶到终点的最少花费是多少?

这题自然想到图上DP,通过最短路来转移方程:

  • dp[u][c]表示当前在u点油箱还有c单位油时的最少花费

不过,我T得好惨,因为在转移时我通过枚举在各个结点加多少油转移,这样对于每个状态都for一遍枚举,整个时间复杂度还得乘上转移的代价,即油箱最大容量。。。

事实上,状态dp[u][c]只需要向两个方向转移:

  • 向dp[u][c+1]转移,即原地加一单位油
  • 向dp[v][c-w(u,v)]((u,v)∈E 且 w(u,v)<=c),即走到下一个结点

另外用SPFA会TLE,用Dijkstra即可,1000×100的状态数稳定AC。

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 1111
#define MAXM 111111 struct Edge{
int v,w,next;
}edge[MAXM<<];
int NE,head[MAXN];
void addEdge(int u,int v,int w){
edge[NE].v=v; edge[NE].w=w; edge[NE].next=head[u];
head[u]=NE++;
} int vs,vt,cap;
int price[MAXN],d[MAXN][];
bool vis[MAXN][]; struct Node{
int u,w,d;
Node(int _u=,int _w=,int _d=):u(_u),w(_w),d(_d){}
bool operator<(const Node &nd)const{
return nd.d<d;
}
}; int dijkstra(){
memset(d,,sizeof(d));
memset(vis,,sizeof(vis));
priority_queue<Node> que;
for(int i=; i<=cap; ++i){
d[vs][i]=price[vs]*i;
que.push(Node(vs,i,d[vs][i]));
}
while(!que.empty()){
Node nd=que.top(); que.pop();
if(nd.u==vt) return nd.d;
if(vis[nd.u][nd.w]) continue;
vis[nd.u][nd.w]=;
if(nd.w<cap && d[nd.u][nd.w+]>d[nd.u][nd.w]+price[nd.u]){
d[nd.u][nd.w+]=d[nd.u][nd.w]+price[nd.u];
que.push(Node(nd.u,nd.w+,d[nd.u][nd.w+]));
}
for(int i=head[nd.u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].w>nd.w) continue;
int nw=nd.w-edge[i].w;
if(d[v][nw]>d[nd.u][nd.w]){
d[v][nw]=d[nd.u][nd.w];
que.push(Node(v,nw,d[v][nw]));
}
}
}
return INF;
} int main(){
int n,m,q,a,b,c;
scanf("%d%d",&n,&m);
for(int i=; i<n; ++i){
scanf("%d",price+i);
}
memset(head,-,sizeof(head));
while(m--){
scanf("%d%d%d",&a,&b,&c);
addEdge(a,b,c);
addEdge(b,a,c);
}
scanf("%d",&q);
while(q--){
scanf("%d%d%d",&cap,&vs,&vt);
int res=dijkstra();
if(res==INF) puts("impossible");
else printf("%d\n",res);
}
return ;
}

POJ3635 Full Tank?(DP + Dijkstra)的更多相关文章

  1. 取数字(dp优化)

    取数字(dp优化) 给定n个整数\(a_i\),你需要从中选取若干个数,使得它们的和是m的倍数.问有多少种方案.有多个询问,每次询问一个的m对应的答案. \(1\le n\le 200000,1\le ...

  2. 洛谷P2507 [SCOI2008]配对 题解(dp+贪心)

    洛谷P2507 [SCOI2008]配对 题解(dp+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1299251 链接题目地址:洛谷P2507 [S ...

  3. [Codeforces722E] Research Rover (dp+组合数学)

    [Codeforces722E] Research Rover (dp+组合数学) 题面 给出一个N*M的方格阵,从(1,1)出发,到(N,M)结束,从(x,y)只能走到(x+1,y)或(x,y+1) ...

  4. POJ-3635 Full Tank? (记忆化广搜)

    Description After going through the receipts from your car trip through Europe this summer, you real ...

  5. POJ 3268 Silver Cow Party (双向dijkstra)

    题目链接:http://poj.org/problem?id=3268 Silver Cow Party Time Limit: 2000MS   Memory Limit: 65536K Total ...

  6. hdoj1874 (优先队列+Dijkstra)

    hdoj1874 分析: 一看题目, 就是求最短路, 这道题用的是Dijkstra+优先队列.先说一下Dijkstra算法:每次扩展一个距离最短的节点, 更新与其相邻点的距离. 当所有边权都为正时, ...

  7. Rikka with Subset HDU - 6092 (DP+组合数)

    As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some mat ...

  8. 合法括号序列(dp+组合数学)

    键盘上有左括号(,右括号),和退格键-,共三个键. 牛牛希望按键n次,使得输入的字符串恰好一个合法的括号序列. 每按一次左括号(,字符串末尾追加一个左括号( 每按一次右括号),字符串末尾追加一个右括号 ...

  9. LightOJ - 1246 Colorful Board(DP+组合数)

    http://lightoj.com/volume_showproblem.php?problem=1246 题意 有个(M+1)*(N+1)的棋盘,用k种颜色给它涂色,要求曼哈顿距离为奇数的格子之间 ...

随机推荐

  1. YAML-初识

    YAML简介 YAML-what? YAML Ain't Markup Language 和GNU一样,YAML是一个递归着说"不"的名字.不同的是,GNU对UNIX说不,YAML ...

  2. Android ArrayAdapter使用

    1. 可以直接使用getContext()获取Context对象 2. 可以在构造方法中传入context, 数据对象的列表, super(context, 0, object);完成Adapter的 ...

  3. LNMP平台搭建---Nginx安装篇

    在上一篇博文<LNMP平台搭建---Linux系统安装篇>中,我们安装了CentOS版本的Linux操作系统,现在,我们来安装一个Web服务器,大标题写着LNMP,其中的N就是Nginx, ...

  4. C#的正则表达式

    using System; using System.Collections; using System.Collections.Generic; using System.IO; using Sys ...

  5. [LeetCode] Search Insert Position

    Given a sorted array and a target value, return the index if the target is found. If not, return the ...

  6. golang exec Command

    package mainimport ( "fmt" "log" "os/exec")func main() { out, err := e ...

  7. Oracle11g在使用exp导出时不导出空表问题的解决办法

    11G中有个新特性,当表无数据时,不分配segment,以节省空间 解决方法: 1.insert一行,再rollback就产生segment了. 该方法是在在空表中插入数据,再删除,则产生segmen ...

  8. 1-02 启动和停止Sql Sever的服务

    启动Sql  Sever服务的三种方式 1:后台启动服务. 2:Sql Sever配置管理员启动服务. 3:在运行窗口中使用命令启动和停止服务: 启动:net start mssqlsever. 停止 ...

  9. 用.NET开发通用Windows App

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:随着Windows 10的正式发布,作为.NET开发人员应该开始或多或少了解一下通用( ...

  10. Build Instructions (Windows) – The Chromium Projects

    转自:http://121.199.54.6/wordpress/?p=1156 原始地址:http://www.chromium.org/developers/how-tos/build-instr ...