(不满足最优子问题,所以不能直接用Dijkstra求解)
最优子问题a到b的结果可由a到c+c到b的结果合并得到
细节:vector 数组可以整体赋值哦!
fill()函数二维数组起始地址edge[0]而不是edge,头文件algorithm
题目大意:每个自行车车站的最大容量为一个偶数cmax,如果一个车站里面自行车的数量恰好为cmax / 2,那么称处于完美状态。如果一个车站容量是满的或者空的,控制中心(处于结点0处)就会携带或者从路上收集一定数量的自行车前往该车站,一路上会让所有的车站沿途都达到完美。现在给出cmax,车站的数量n,问题车站sp,m条边,还有距离,求最短路径。如果最短路径有多个,求能带的最少的自行车数目的那条。如果还是有很多条不同的路,那么就找一个从车站带回的自行车数目最少的(带回的时候是不调整的)~
分析:Dijkstra + DFS。如果只有Dijkstra是不可以的,因为minNeed和minBack在路径上的传递不满足最优子结构,不是简单的相加的过程,只有在所有路径都确定了之后才能区选择最小的need和最小的back~
Dijkstra求最短路径,dfs求minNeed和minBack和path,dfs的时候模拟一遍需要调整的过程,求出最后得到的need和back,与minNeed和minBack比较然后根据情况更新path,最后输出minNeed path 和 minBack,记得path是从最后一个结点一直到第一个结点的,所以要倒着输出~
#include<stdio.h> #include<vector> #include<algorithm> #pragma warning(disable:4996) #define INF 0xfffffff using namespace std; int cmax, n, m, sp; int d[510], vis[510], bike[510]; int edge[510][510]; vector<int>res, tmp, pre[510]; int minback =INF, minsend=INF; void dfs(int v) { tmp.push_back(v); if (0 == v) { int back = 0, send = 0; for (int i = tmp.size() - 1; i >= 0; i--) { if (bike[tmp[i]] > 0) { back += bike[tmp[i]]; } else { if (back > (0 - bike[tmp[i]])) { back += bike[tmp[i]]; } else { send += (0 - bike[tmp[i]] - back); back = 0; } } } if (send < minsend) { minsend = send; minback = back; res = tmp; } else if (send == minsend && back < minback) { minback = back; res = tmp; } tmp.pop_back(); return; } for (int i = 0; i < pre[v].size(); i++) dfs(pre[v][i]); tmp.pop_back(); } int main() { fill(edge[0],edge[0]+510*510,INF); fill(d, d + 510, INF); scanf("%d%d%d%d",&cmax,&n,&sp,&m); for (int i = 1; i <= n; i++) { scanf("%d", &bike[i]), bike[i] -= cmax / 2; } for (int i = 1,a,b,c; i <= m; i++) { scanf("%d%d%d", &a, &b,&c); edge[a][b] = edge[b][a] = c; } d[0] = 0; for (int i = 0; i <= n; i++) { int u = -1, min = INF; for (int j = 0; j <= n; j++) { if (0 == vis[j] && d[j] < min) { u = j; min = d[j]; } } if (-1 == u) break; vis[u] = 1; for (int v = 0; v <= n; v++) { if (0 == vis[v] && edge[u][v] != INF) { if (d[v] > d[u] + edge[u][v]) { d[v] = d[u] + edge[u][v]; pre[v].clear(); pre[v].push_back(u); } else if (d[v] == d[u] + edge[u][v]) { pre[v].push_back(u); } } } } dfs(sp); printf("%d ",minsend); int i = res.size() - 1; for (; i > 0; i--){ printf("%d->", res[i]); } printf("%d ", res[i]); printf("%d", minback); getchar(); getchar(); return 0; }