back不具有最优子结构,不能单纯用dijkstra解,找出所有最短可能路径dfs进行比较
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
struct node {
int to, lg;
node() {};
node(int t, int l):to(t), lg(l) {}
};
const int MAXN = 510;
const int MAX = 0x3f3f3f3f;
vector<node> mp[MAXN];
int num[MAXN];
int dist[MAXN];
vector<int> fa[MAXN];
int c, n, en;
void dij() {
memset(dist, 0x3f, sizeof(dist));
dist[0] = 0;
bool book[MAXN];
memset(book, false, sizeof(book));
for (int i = 0; i <= n; i++) {
int u = n+1;
for (int j = 0; j <= n; j++)
if (!book[j] && dist[j] < dist[u])
u = j;
book[u] = true;
for (vector<node>::iterator it = mp[u].begin(); it != mp[u].end(); it++)
if (dist[u] + it->lg < dist[it->to]) {
dist[it->to] = dist[u] + it->lg;
fa[it->to].clear();
fa[it->to].push_back(u);
} else if (dist[u] + it->lg == dist[it->to])
fa[it->to].push_back(u);
}
}
int cnt = 0, send = MAX, back = MAX, len;
int path[MAXN], ans[MAXN];
void dfs(int x) {
if (x == 0) {
int se = 0, ba = 0;
for (int i = cnt-1; i >= 0; i--) {
ba += num[path[i]] - c;
if (ba < 0) {
se -= ba;
ba = 0;
}
}
if (se < send || se == send && ba < back) {
send = se;
back = ba;
len = cnt;
for (int i = 0; i < len; i++)
ans[i] = path[len-1-i];
}
}
path[cnt++] = x;
for (vector<int>::iterator it = fa[x].begin(); it != fa[x].end(); it++)
dfs(*it);
cnt--;
}
int main() {
int m;
scanf("%d%d%d%d", &c, &n, &en, &m);
for (int i = 1; i <= n; i++)
scanf("%d", num+i);
while (m--) {
int x, y, l;
scanf("%d%d%d", &x, &y, &l);
mp[x].push_back(node(y, l));
mp[y].push_back(node(x, l));
}
c /= 2;
dij();
dfs(en);
printf("%d 0", send);
for (int i = 0; i < len; i++)
printf("->%d", ans[i]);
printf(" %d\n", back);
return 0;
}