用分支界限法求解下面的问题并给出C++代码 小李希望开车到全国各地旅游,他发现旅途中各个城市的汽油价格也不相同,显然如果能够采取合理的加油方式,将会节省整个旅途的费用。假设汽车开始时油箱为空,汽车每走一个单位的距离将耗费一个单位的汽油。请帮助小李找到一种最省钱的方式完成他的整个自驾游。 输入要求: 输入的第一行包含两个整数n (1 ≤ n ≤ 1000)和m(0 ≤ m ≤ 10000),分别表示城市的数量以及道路的数量。其后的一行包含n个整数,分别表示n个城市的汽油价格。其后的m行,每一行包含三个整数u,v,d,表示城市u,v之间的距离为d(1 ≤ d ≤ 100)。最后一行包含三个整数c( 1 ≤ c ≤ 100),s,e,分别表示油箱的容量,出发的城市和最后到达的城市。 输出要求: 如果能够帮助小李找到一个最省钱从s到e的路线,则输出对应的费用,否则输出“impossible”。 样例输入: 5 5 10 10 20 12 13 0 1 9 0 2 8 1 2 1 1 3 11 2 3 7 10 0 3 样例输出: 170
时间: 2024-03-31 14:38:56 浏览: 233
以下是用分支界限法求解小李自驾游问题的C++代码:
```c++
#include <iostream>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1005;
const int MAXM = 10005;
struct Edge {
int v;
int w;
int c;
};
vector<Edge> adj[MAXN];
int dis[MAXN][MAXN];
int oil[MAXN];
int n, m, c, s, e;
int ans = INT_MAX;
struct Node {
int u;
int cost;
int dist;
int oil;
vector<int> path;
Node(int u, int cost, int dist, int oil, vector<int> path) {
this->u = u;
this->cost = cost;
this->dist = dist;
this->oil = oil;
this->path = path;
}
};
struct cmp {
bool operator() (const Node& a, const Node& b) {
return a.cost + a.dist > b.cost + b.dist;
}
};
void dijkstra(int s) {
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
memset(dis[s], 0x3f, sizeof(dis[s]));
dis[s][s] = 0;
q.push({0, s});
while (!q.empty()) {
int u = q.top().second;
int d = q.top().first;
q.pop();
if (d != dis[s][u]) continue;
for (auto& e : adj[u]) {
int v = e.v;
int w = e.w;
if (dis[s][v] > dis[s][u] + w) {
dis[s][v] = dis[s][u] + w;
q.push({dis[s][v], v});
}
}
}
}
void dfs(int u, int cost, int dist, int oil, vector<int> path) {
if (cost >= ans) return;
if (u == e) {
ans = cost;
return;
}
for (auto& e : adj[u]) {
int v = e.v;
int w = e.w;
if (w > oil) continue;
int new_cost = cost + e.c * (w - oil);
int new_dist = dist + w;
int new_oil = oil - w + ::oil[v];
if (new_oil > c) new_oil = c;
vector<int> new_path(path);
new_path.push_back(v);
if (new_cost < ans) {
dfs(v, new_cost, new_dist, new_oil, new_path);
}
}
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> oil[i];
}
for (int i = 0; i < m; i++) {
int u, v, d;
cin >> u >> v >> d;
adj[u].push_back({v, d, oil[v]});
adj[v].push_back({u, d, oil[u]});
}
cin >> c >> s >> e;
for (int i = 0; i < n; i++) {
dijkstra(i);
}
vector<int> path;
path.push_back(s);
dfs(s, 0, 0, c - oil[s], path);
if (ans == INT_MAX) cout << "impossible" << endl;
else cout << ans << endl;
return 0;
}
```
代码中,我们首先使用Dijkstra算法预处理出各个城市之间的最短路。然后,我们定义状态为当前所在城市、当前油量、已经走过的路径,并对状态进行扩展。在扩展状态时,我们计算从当前城市到达下一个城市所需要的油量和费用,如果当前油价加上这个费用小于已知最优路径,则将这个状态加入待探索状态集合中。在扩展状态时,我们还需要计算当前状态到目标城市e的最小花费,如果该下界已经大于已知最优路径,则剪枝。最终,我们可以在有限的时间内求解小李自驾游问题的最优解。
阅读全文