POJ 3635 Full Tank? (最短路变形,BFS+优先队列)
2013-04-22 20:13
323 查看
【题意】
给你 n 个点,m 条边,每走 1 单位的路径都会花费 1 单位的 fuel ,并且不同的点灌油的油的价格是不同的,现在给你一些询问,每一个询问给你起点、终点以及油箱的容量,问你所需要的最少的花费可以从起点到达终点。
涉及两个维的图最短路,一个是费用,一个是地点。(比如在位置0有1升油是一个点,在位置0有2升油又是另外一个点)
如果把这个点抽象出来,把费用看过边,那么最少费用就可以类似dijsktra算法那样不断的加入点。
于是得到一个扩展结点的策略:
1.每一次加一升油(因为题目的条件这些都是整数,所以可以类似离散化处理,一点一点加入油)
2.如果加的油足够走到下一个结点,那就走到下一个结点吧(记得减去路上消耗的油,还有花费不变...)
(至于在第二次扩展时要不要加油,这个就不需要了.因为在第一种情况扩展结点的时候加油了...)
这里的BFS是把所有可扩展的节点都加入优先队列中,而Dijkstra是每次松弛了的点才加入,中间少了很多状态。但是思想都是一样的。不知道这题能不能像Dij那样做。
给你 n 个点,m 条边,每走 1 单位的路径都会花费 1 单位的 fuel ,并且不同的点灌油的油的价格是不同的,现在给你一些询问,每一个询问给你起点、终点以及油箱的容量,问你所需要的最少的花费可以从起点到达终点。
涉及两个维的图最短路,一个是费用,一个是地点。(比如在位置0有1升油是一个点,在位置0有2升油又是另外一个点)
如果把这个点抽象出来,把费用看过边,那么最少费用就可以类似dijsktra算法那样不断的加入点。
于是得到一个扩展结点的策略:
1.每一次加一升油(因为题目的条件这些都是整数,所以可以类似离散化处理,一点一点加入油)
2.如果加的油足够走到下一个结点,那就走到下一个结点吧(记得减去路上消耗的油,还有花费不变...)
(至于在第二次扩展时要不要加油,这个就不需要了.因为在第一种情况扩展结点的时候加油了...)
这里的BFS是把所有可扩展的节点都加入优先队列中,而Dijkstra是每次松弛了的点才加入,中间少了很多状态。但是思想都是一样的。不知道这题能不能像Dij那样做。
#include #include #include #include #include #include #include #include #include #include #include #include #define MID(x,y) ((x+y)>>1) #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; struct node{ int u, v, w; int next; }edge[20003]; struct Status{ int u, fuel, cost; friend bool operator < (const Status n1, const Status n2){ return n2.cost < n1.cost; } }; int head[1003], cnt; int n, m; int price[1003]; void init(){ mem(head, -1); cnt = 0; } void add(int u, int v, int w){ edge[cnt].u = u; edge[cnt].v = v; edge[cnt].w = w; edge[cnt].next = head[u]; head[u] = cnt ++; return ; } priority_queue > PQ; bool vis[1003][103]; void push_PQ(int u, int f, int c){ Status tmp; tmp.u = u; tmp.fuel = f; tmp.cost = c; PQ.push(tmp); } int BFS(int c, int s, int e){ mem(vis, 0); while(!PQ.empty()){ PQ.pop(); } push_PQ(s, 0, 0); while(!PQ.empty()){ Status tmp = PQ.top(); PQ.pop(); int u = tmp.u, fuel = tmp.fuel, cost = tmp.cost; vis[u][fuel] = 1; if (u == e){ return cost; } // we choose to add a unit fuel; if (fuel < c && !vis[u][fuel+1]){ push_PQ(u, fuel+1, cost+price[u]); } // we choose to go to the next node; for (int i = head[u]; i != -1; i = edge[i].next){ if (fuel >= edge[i].w && !vis[edge[i].v][fuel-edge[i].w]){ push_PQ(edge[i].v, fuel-edge[i].w, cost); } } } return -1; } int main(){ init(); scanf("%d %d", &n, &m); for (int i = 0; i < n; i ++){ scanf("%d", &price[i]); } for (int i = 0; i < m; i ++){ int tmpu, tmpv, tmpw; scanf("%d %d %d", &tmpu, &tmpv, &tmpw); add(tmpu, tmpv, tmpw); add(tmpv, tmpu, tmpw); } int q, c, s, e;; scanf("%d", &q); while(q --){ scanf("%d %d %d", &c, &s, &e); int ans = BFS(c, s, e); if (ans == -1){ puts("impossible"); } else{ printf("%d\n", ans); } } return 0; }
相关文章推荐
- POJ 3635 Full Tank? (最短路变形,BFS+优先队列)
- POJ-3635 Full Tank? 变形最短路
- POJ 3635 Full Tank? 最短路变形
- POJ 3635 Full Tank(最短路径变形 + 优先队列)
- Full Tank? POJ - 3635 二维最短路(dp?)
- poj 3635/hdu 1676 Full Tank? 车辆加油+最短路
- poj 3635/hdu 1676 Full Tank? 车辆加油+最短路
- POJ 3635 Full Tank? 最短路DP
- poj 3635 Full Tank 最短路
- POJ 3635 Full Tank?
- POJ 3635 Full Tank?
- POJ3635 周游诸城:变形的SPFA/Dijkstra最短路+动规思想+Heap
- POJ 3635 Full Tank?
- [POJ 3635] Full Tank?
- POJ 3635 Full Tank? 拆点建图+dijkstra
- poj 3635(full tank?)
- poj 3635 Full Tank? ( 图上dp )
- POJ 3635 bfs+优先队列(最短路本质,好题)
- poj 3635 Full Tank? ( bfs+dp思想 )
- POJ-3635 Full Tank? (记忆化广搜)