题目:https://pintia.cn/problem-sets/994805342720868352/problems/994805489282433024
我用的是Dijkstra+DFS,Dijkstra问题不大,问题出在DFS中,我没有注意到题中,回来的时候不能补齐车,所以我用的“sum”就错了。要像“油箱”题一样计算。还要注意有些循环中端点是1,以及初始化的位置。
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int INF = 1e9;
const int maxn = 510;
int G[maxn][maxn], d[maxn], w[maxn] = {0}, sum = 0, back;
int c, n, sp, m;
bool vis[maxn] = {false};
vector<int> temp, path, pre[maxn];
void Dijkstra(){
d[0] = 0;
for(int i = 0; i <= n; i++){
int u = -1, MIN = INF;
for(int j = 0; j <= n; j++){
if(!vis[j] && d[j] < MIN){
MIN = d[j];
u = j;
}
}
if (u == -1)
return;
vis[u] = true;
for(int v = 1; v <= n; v++){
if(!vis[v] && G[u][v] != INF){
if(d[u] + G[u][v] < d[v]){
d[v] = d[u] + G[u][v];
pre[v].clear();
pre[v].push_back(u);
}
else if(d[u] + G[u][v] == d[v]){
pre[v].push_back(u);
}
}
}
}
}
int minNeed = INF, minRemain = INF;
void DFS(int v){
temp.push_back(v);
if(!v){
int remain = 0, need = 0;
for(int i = temp.size() - 2 ; i >= 0; i--){
int u = temp[i];
if(w[u] >= 0){
remain += w[u];
}
else{
if(remain >= -w[u])
remain += w[u];
else{
need += -w[u] - remain;
remain = 0;
}
}
}
if(need < minNeed){
minNeed = need;
minRemain = remain;
path = temp;
}
else if(need == minNeed){
if(remain < minRemain){
minNeed = need;
minRemain = remain;
path = temp;
}
}
return;
}
for(int i = 0; i < pre[v].size(); i++){
DFS(pre[v][i]);
temp.pop_back();
}
}
int main(){
scanf("%d%d%d%d", &c, &n, &sp, &m);
fill(w+1, w + maxn, -c/2);
for(int i = 1; i <= n; i++){
int weight;
scanf("%d", &weight);
w[i] += weight;
}
fill(G[0], G[0] + maxn * maxn, INF);
for(int i = 0; i < m; i++){
int a, b, t;
scanf("%d%d%d", &a, &b, &t);
G[a][b] = t;
G[b][a] = t;
}
fill(d, d + maxn, INF);
Dijkstra();
DFS(sp);
printf("%d ", minNeed);
for(int i = path.size() - 1; i >= 0; i--){
printf("%d",path[i]);
if(i){
printf("->");
}
}
printf(" %d", minRemain);
return 0;
}