注:这里用到了Dijkstra和DFS
注2:需要找出所有路径,然后才能选择最小的minNeed,minTake
注3:need(需要的bikes数量)要进行累加
注4:相同长度的最短路径,选择need最少的;如果这时need也相同,则选择take最少的;
#include <stdio.h>
#include <string.h>
#include <deque>
#include <stdlib.h>
#define INF 9999999
using namespace std;
int cmax, n, sp, m;
int map[501][501];
int bikes[501];
int set[501];
int dist[501];
deque<int> route[501];
deque<int> path;
deque<deque<int> > paths;
bool finished();
void dfsTraverse(int sp, deque<int> path);
void getNeedTake(deque<int> dq, int &need, int &take);
int main(int argc, char *argv[]) {
int i, j, k;
int a, b, c;
scanf("%d %d %d %d", &cmax, &n, &sp, &m);
n++;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (i == j) map[i][j] = 0;
else map[i][j] = INF;
}
}
for (i = 1; i < n; i++)
scanf("%d", &bikes[i]);
for (i = 0; i < m; i++) {
scanf("%d %d %d", &a, &b, &c);
map[a][b] = map[b][a] = c;
}
memset(set, 0, 501 * sizeof(int));
for (i = 0; i < n; i++)
dist[i] = INF;
set[0] = 1;
dist[0] = 0;
int point = 0;
route[0].push_back(-1);
while(!finished()) {
for (i = 0; i < n; i++) {
if (set[i] == 1) continue;
if (dist[i] > dist[point] + map[point][i]) {
dist[i] = dist[point] + map[point][i];
route[i].clear();
route[i].push_back(point);
} else if (dist[i] == dist[point] + map[point][i]) {
route[i].push_back(point);
}
}
int min = INF;
int minIndex = 0;
for (j = 0; j < n; j++) {
if (set[j] == 0 && dist[j] < min) {
min = dist[j];
minIndex = j;
}
}
point = minIndex;
set[point] = 1;
}
dfsTraverse(sp, path);
int need, take;
int minNeed = INF;
int minTake = INF;
int index = 0;
for (i = 0; i < paths.size(); i++) {
getNeedTake(paths[i], need, take);
if (need < minNeed ) {
minNeed = need;
minTake = take;
index = i;
} else if (need == minNeed) {
if (take < minTake) {
minTake = take;
index = i;
}
}
}
printf("%d ", minNeed);
for (i = 0; i < paths[index].size(); i++) {
printf("%d", paths[index][i]);
if (i < paths[index].size() - 1)
printf("->");
else printf(" ");
}
printf("%d\n", minTake);
return 0;
}
void dfsTraverse(int sp, deque<int> path) {
if (sp == -1) {
paths.push_front(path);
return;
}
path.push_front(sp);
for (int i = 0; i < route[sp].size(); i++) {
dfsTraverse(route[sp].at(i), path);
}
}
bool finished() {
for(int i = 0; i < n; i++) {
if (set[i] == 0) return false;
}
return true;
}
void getNeedTake(deque<int> dq, int &need, int &take) {
int a[501];
a[0] = 0;
for (int i = 1; i < dq.size(); i++) {
int tmp = bikes[dq[i]] - cmax / 2;
if (tmp >= 0 && a[i - 1] < 0)
a[i] = tmp;
else
a[i] = a[i - 1] + tmp;
}
int sum = 0;
for (int i = 0; i < dq.size() - 1; i++) {
if (a[i] < 0 && a[i + 1] >= 0) {
sum += a[i] * (-1);
}
}
if (a[dq.size() - 1] < 0)
sum += a[dq.size() - 1] * (-1);
need = sum;
take = (a[dq.size() - 1] > 0 ? a[dq.size() - 1] : 0);
}