题目太长就不抄了,这题得做个重点记号,比较典型。
#include <cstdio>
#include <vector>
#include <stack>
using namespace std;
int cMax, N, Sp, M, cap[510] = {0}, G[510][510] = {0}, visited[510] = {0};
int dis[510] = {0}, inf = 1000000000, give[510] = {0};
vector<int> fore[510], path ,ans;
int minCnt = inf, minTake = inf;
void dfs(int v){
//已找到一条路径
if(v == 0){
path.push_back(v);
//cnt为当前点多余的车,take记录要带的车
int cnt = 0, take = 0;
for(int i = path.size() - 1; i >= 0; i--){
if(cnt + cap[path[i]] <= 0){
take -= (cnt + cap[path[i]]);
cnt = 0;
}
else
cnt += cap[path[i]];
}
if(take < minTake){
minTake = take;
ans = path;
minCnt = cnt;
}
else if(take == minTake && cnt < minCnt){
ans = path;
minCnt = cnt;
}
path.pop_back();
return;
}
path.push_back(v);//将当前节点放到路径中
for(int i = 0; i < fore[v].size(); i++)
dfs(fore[v][i]);
path.pop_back();//将当前节点从路径中去掉,找其他的路
}
int main(){
scanf("%d%d%d%d", &cMax, &N, &Sp, &M);
cMax /= 2;
for(int i = 1; i <= N; i++){
scanf("%d", &cap[i]);
cap[i] -= cMax;
dis[i] = inf;
}
for(int i = 0; i < M; i++){
int f, t, w;
scanf("%d%d%d", &f, &t, &w);
G[f][t] = G[t][f] = w;
}
//dijkstra
for(int i = 0; i <= N; i++){
int index = -1, min = inf;
for(int j = 0; j <= N; j++){
if(visited[j] == 0 && dis[j] < min){
index = j;
min = dis[j];
}
}
if(index == -1)
break;
visited[index] = 1;
for(int j = 0; j <= N; j++){
//printf("index is %d\n", index);
if(G[index][j] != 0){
if(dis[index] + G[index][j] < dis[j]){
dis[j] = dis[index] + G[index][j];
fore[j].clear();
fore[j].push_back(index);
}
//cnt用来保存当前节点多余的bike
else if(dis[index] + G[index][j] == dis[j]){
fore[j].push_back(index);
}
}
}
}
dfs(Sp);
printf("%d ", minTake);
for(int i = ans.size() - 1; i >= 0; i--){
if(i > 0)
printf("%d->", ans[i]);
else
printf("%d ", ans[i]);
}
printf("%d\n", minCnt);
return 0;
}