搜索_BFS_优先队列BFS_POJ3635_Full Tank?

版权声明:本文为博主原创作品, 转载请注明出处! https://blog.csdn.net/solider98/article/details/84312761

点此打开题目页面

思路分析:

    考虑使用优先队列BFS, 解空间树中的每个状态对应一个三元组(i, j, k), 表示从城市i出发时剩余油量为j升的最小花费为k, 对于每一个状态三元组Q如果j < c, (c为油箱容量) 那么可从Q扩展至状态(i, j + 1, p), 如果u与i之间存在长度为d的路, 且j >= d, 那么可从Q扩展至状态(u, j - d, r), 具体实现如下AC代码所示:

//POJ3635_Full Tank?
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#include <deque>
#include <algorithm>
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
const int MAXN = 1e3 + 5, MAXM = 1e4 + 5, MAXC = 105, NIL = 0x3f3f3f3f;
int n, m, pr[MAXN], d[MAXN][MAXC];//d[i][j]:到达城市i, 剩余j单位油的最小费用, pr[i]:城市i的油价 
int head[MAXN], ver[MAXM * 2 + 5], nex[MAXM * 2 + 5], we[MAXM * 2 + 5], tot;
struct cmp{
	bool operator()(const pair<int, pii> &a, const pair<int, pii> &b){
		return a.fi > b.fi;
	}
};
int main(){
	scanf("%d %d", &n, &m);
	for(int i = 0; i < n; ++i) scanf("%d", &pr[i]);
	for(int i = 1, u, v, w; i <= m; ++i){
		scanf("%d %d %d", &u, &v, &w);
		if(!head[u]) ver[++tot] = v, head[u] = tot, we[tot] = w;
		else ver[++tot] = v, we[tot] = w, nex[tot] = head[u], head[u] = tot;
		if(!head[v]) ver[++tot] = u, head[v] = tot, we[tot] = w;
		else ver[++tot] = u, we[tot] = w, nex[tot] = head[v], head[v] = tot;
	}
	int q; scanf("%d", &q);
	while(q--){
		int c, s, e; scanf("%d %d %d", &c, &s, &e); memset(d, 0x3f, sizeof(d));
		priority_queue<pair<int, pii>, vector<pair<int, pii> >, cmp> pq; 
		pq.push(mp(0, mp(s, 0))), d[s][0] = 0; int res = NIL;
		while(!pq.empty()){
			int fi = pq.top().se.fi, se = pq.top().se.se, w = pq.top().fi; pq.pop();
			if(fi == e){
				res = w; break;
			}
			//本城市加油
			if(se < c && d[fi][se] + pr[fi] < d[fi][se + 1]) 
				d[fi][se + 1] = d[fi][se] + pr[fi], pq.push(mp(d[fi][se + 1], mp(fi, se + 1)));
			//到相邻城市加油
			for(int i = head[fi]; i; i = nex[i])
				if(se >= we[i] && d[fi][se] < d[ver[i]][se - we[i]]) 
					d[ver[i]][se - we[i]] = d[fi][se]
					, pq.push(mp(d[ver[i]][se - we[i]], mp(ver[i], se - we[i])));
		}
		if(res == NIL) cout << "impossible" << endl; else cout << res << endl; 
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/solider98/article/details/84312761