用的BFS+优先队列+二进制压缩状态判重+链式前向星, TLE,好像有人这样过了。。。好像要用A*算法,还不太会,所以暂时放弃。但是也学会了很多,学习了链式前向星,更深理解了BFS求最优的时候,什么时候是第一次搜到结果就是最优,该题,通过枚举加的油量,每次加一个单位,从够下一条路开始到满容量,枚举所有路,花的钱少的在队优先(头),故先出队找到目标结点的必然最优,因为后面的都是前面再加钱的。。。。好好想想。。。

#include<iostream>  //链式前向星+二进制状态压缩判重+优先队列
#include<queue>
#include<cstring>
#include<cstdio>
using namespace std;
int prize[1002];
struct edge
{
int pre; //该边关于该点的前一条边
int to; //通哪个点
int w; //权
};
struct state
{
int dian;
int key; //二进制压缩判重
int cur_money;
int cur_fuel;
state()
{
key=0;
}
bool operator <(const state & a)const //按花费小的排序
{
return a.cur_money<cur_money;
}
};
edge bian[20002];
int head[1002]; //每个顶点的边的头指针
int mincost=0x3f3f3f3f;
void bfs(int from,int capacity,int to)
{
priority_queue<state>q;
state start;
start.dian=from;
start.key=(start.key|(1<<from));
start.cur_fuel=0;
start.cur_money=0;
q.push(start);
while(!q.empty())
{
state cur=q.top();
q.pop();
if(cur.cur_money>=mincost)continue;
if(cur.dian==to)
{
if(cur.cur_money<mincost)
mincost=cur.cur_money;
return;
//continue;
}
for(int j=head[cur.dian];j!=-1;j=bian[j].pre) //枚举边
{
if ((cur.key&(1<<bian[j].to))!=0)continue; //判重(后来知道这样判重是不对的,可以重顶点,要顶点+油量双重判重才可以)
for(int i=0;i+cur.cur_fuel<=capacity;i++) //充i油,前进。
{
state next(cur);
if(cur.cur_fuel+i<bian[j].w)continue; //不够路费的剪枝
next.cur_fuel=next.cur_fuel+i-bian[j].w;
next.cur_money=next.cur_money+i*prize[cur.dian];
if(next.cur_money>=mincost)break; //最优性剪枝
next.dian=bian[j].to;
if(next.dian==to)
{
if(next.cur_money<mincost)
mincost=next.cur_money;
break;
}
q.push(next);
next.key=(next.key|(1<<bian[j].to));
}
}
}
return ;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d",&prize[i]);
int s,e,lenth;
memset(head,-1,sizeof(head));
for(int i=0;i<2*m;i++)
{
scanf("%d%d%d",&s,&e,&lenth);
bian[i].to=e;
bian[i].pre=head[s]; //head[s]:顶点s的某边,只是暂时存储,链接俩个边关系作用。
head[s]=i;
bian[i].w=lenth;
i++;
bian[i].to=s;
bian[i].pre=head[e]; //head[s]:顶点s的某边,只是暂时存储,链接俩个边关系作用。
head[e]=i;
bian[i].w=lenth;
}
/*for(int k=0;k<n;k++)
for(int j=head[k];j!=-1;j=bian[j].pre) //枚举边
{
printf("%d to %d has %d\n",k,bian[j].to,bian[j].w);
}*/
int que;scanf("%d",&que);
int capacity,from,to;
while(que--)
{
mincost=0x3f3f3f3f;
scanf("%d%d%d",&capacity,&from,&to);
if(head[to]==-1||head[from]==-1){printf("impossible\n");continue;}//无解
bool mark1=1;
for(int j=head[from];j!=-1;j=bian[j].pre) //枚举边
{
if(bian[j].w<=capacity){mark1=0;break;}
}
bool mark2=1;
for(int j=head[to];j!=-1;j=bian[j].pre) //枚举边
{
if(bian[j].w<=capacity){mark2=0;break;}
}
if(mark1||mark2){printf("impossible\n");continue;} //无解
bfs(from,capacity,to);
if(mincost!=0x3f3f3f3f)printf("%d\n",mincost);
else printf("impossible\n");
}
return 0;
}

poj3635 FULL tank(TLE) 有限制的最短路(BFS搜索)。的更多相关文章

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

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

  2. POJ3635 Full Tank?(DP + Dijkstra)

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

  3. POJ3635 Full Tank?【Dijkstra+DP】

    题意: n个城市之间有m条双向路.每条路要耗费一定的油量.每个城市的油价是固定并且已经给出的.有q个询问,表示从城市s走到e,油箱的容量为c,求最便宜的方案. 思路: 用Dijkstra+Heap即可 ...

  4. POJ3635 Full Tank?

    [题解] 用dijkstra算法求最短路.同时考虑在每个节点加油(一单位)与否. [代码] #include <iostream> #include <map> #includ ...

  5. POJ3635 Full Tank? 优先队列BFS or 分层图最短路 or DP?

    然而我也不知道这是啥啊...反正差不多...哪位大佬给区分一下QWQ.. 好的,我把堆的<写反了..又调了一个小时..你能不能稳一点.... 记录状态:所在位置u,油量c,花费w 扩展状态: 1 ...

  6. poj练习题的方法

    poj1010--邮票问题 DFSpoj1011--Sticks dfs + 剪枝poj1020--拼蛋糕poj1054--The Troublesome Frogpoj1062--昂贵的聘礼poj1 ...

  7. 2014 UESTC暑前集训搜索专题解题报告

    A.解救小Q BFS.每次到达一个状态时看是否是在传送阵的一点上,是则传送到另一点即可. 代码: #include <iostream> #include <cstdio> # ...

  8. csuoj 1511: 残缺的棋盘

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1511 1511: 残缺的棋盘 时间限制: 1 Sec  内存限制: 128 MB 题目描述 输入 ...

  9. hiho_1139_二分+bfs搜索

    题目 给定N个点和M条边,从点1出发,到达点T.寻找路径上边的个数小于等于K的路径,求出所有满足条件的路径中最长边长度的最小值. 题目链接:二分     最小化最大值,考虑采用二分搜索.对所有的边长进 ...

随机推荐

  1. java实现批量修改指定文件夹下所有后缀名的文件为另外后缀名的代码

    java实现批量修改指定文件夹下所有后缀名的文件为另外后缀名的代码 作者:Vashon package com.ywx.batchrename; import java.io.File; import ...

  2. sqlserver2012 offset

    /* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public Lic ...

  3. Linux OpenGL 实践篇-9 模型

    之前一直渲染箱子,显得有点单调.这一次我们绘制一个用艺术家事先用建模工具创建的模型. 本次实践参考:https://learnopengl-cn.github.io/03%20Model%20Load ...

  4. Java数据结构和算法(二)--队列

    上一篇文章写了栈的相关知识,而本文会讲一下队列 队列是一种特殊的线性表,在尾部插入(入队Enqueue),从头部删除(出队Dequeue),和栈的特性相反,存取数据特点是:FIFO Java中queu ...

  5. JavaScript操作数组。

    1.shift:删除原数组第一项,并返回删除元素的值,原数组为空则返回undefined. 2.unshift:将参数添加到原数组开头,并返回数组的长度. 3.pop:删除原数组最后一项,并返回删除元 ...

  6. treeTable的使用(ajax异步获取数据,动态渲染treeTable)

    一.展示效果(treetable基本样式https://www.cnblogs.com/shuihanxiao/p/10413454.html) 二.html文件(若一个页面又多个treetable, ...

  7. BZOJ1232: [Usaco2008Nov]安慰奶牛cheer(最小生成树)

    题意:给一个图 需要找到一个子图使得所有点都连通 然后再选择一个点做为起点 走到每个点并回到起点 每条边,每个点被经过一次就要花费一次边权.点权 题解:肯定是找一颗最小生成树嘛 然后惊奇的发现 任意选 ...

  8. python调用aapt工具直接获取包名和tagertSdkversion

    背景: 每次海外游戏上架都需要符合google的上架规则,其中适配方面tagetSdkversion有硬性要求,比如需要适配安卓q就需要tagetSdkversion达到28,水平太渣的我每次调用aa ...

  9. spring中注解的实现原理

    @Autowired和@Resource的区别: 在Java中使用@Autowired和@Resource注解进行装配,这两个注解分别是:1.@Autowired按照默认类型(类名称)装配依赖对象,默 ...

  10. 面试奇遇 -- 原生JS

    最近几日去参加一些面试,多多少少有一些收获. 现将遇到的一些面试题,做一下分析和总结. 1.使用原生JS,不能使用递归,查找dom中所有以“<com-”开头的自定义标签tagName. < ...