n个点m条无向边的图,油箱有上限,每个单位的汽油能走1单位距离,每个城市的油价val[i], 对于每个query,求s到e的最小花费。
dp[i][j]表示到达第i个城市,油箱剩余油量j时的最小花费。用bfs扩充节点,每个点拆成100个节点,时间复杂度还是可以接受的。
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<fstream> #include<sstream> #include<bitset> #include<vector> #include<string> #include<cstdio> #include<cmath> #include<stack> #include<queue> #include<stack> #include<map> #include<set> #define FF(i, a, b) for(int i=a; i<b; i++) #define FD(i, a, b) for(int i=a; i>=b; i--) #define REP(i, n) for(int i=0; i<n; i++) #define CLR(a, b) memset(a, b, sizeof(a)) #define debug puts("**debug**") #define LL long long #define PB push_back using namespace std; const int maxn = 1010; int n, m, val[maxn], dp[maxn][101]; int Q, C, S, E; struct Node { int u, cost, res;//当前节点,花费,剩余油量 bool operator < (const Node rhs) const { return cost > rhs.cost; } }; struct Edge { int to, dist; }; vector<Edge> edges; vector<int> G[maxn]; inline void init() { REP(i, n) G[i].clear(); edges.clear(); } void add(int a, int b, int c) { edges.PB((Edge){b, c}); edges.PB((Edge){a, c}); int nc = edges.size(); G[a].PB(nc-2); G[b].PB(nc-1); } void bfs() { REP(i, n) REP(j, C+1) dp[i][j] = 0; priority_queue<Node> q; q.push((Node){S, 0, 0}); while(!q.empty()) { Node x = q.top(); q.pop(); int u = x.u, cost = x.cost, res = x.res, nc = G[x.u].size(); if(u == E) { printf("%d\n", cost); return ; } //考虑当前状态,再多加一点油是否会是更优解 if(res<C && (dp[u][res+1]==0 || dp[u][res+1]>cost+val[u])) dp[u][res+1] = cost+val[u],q.push((Node){u,dp[u][res+1],res+1}); REP(i, nc) { int v = edges[G[u][i]].to, dist = edges[G[u][i]].dist; if(res < dist) continue; //如果油量不够走到下一个节点就continue //如果靠当前油量走到下一个节点会是更优解 if(dp[v][res-dist] == 0 || dp[v][res-dist] > cost) dp[v][res-dist] = cost, q.push((Node){v, cost, res-dist}); } } puts("impossible"); return ; } int main() { while(~scanf("%d%d", &n, &m)) { init(); REP(i, n) scanf("%d", &val[i]); int a, b, c; REP(i, m) { scanf("%d%d%d", &a, &b, &c); add(a, b, c); } scanf("%d", &Q); while(Q--) { scanf("%d%d%d", &C, &S, &E); bfs(); } } return 0; }