题意
每个自行车车站的最大容量为一个偶数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是从最后一个结点一直到第一个结点的,所以要倒着输出
AC代码
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int INF = 999999999;
bool visit[505] = {false};
int weight[505];
int dis[505];
int e[505][505];
vector<int> pre[505];
int c,n,p,m;
int minNeed=INF,minBack=INF;
vector<int> tmp,final;
void dfs(int index){
tmp.push_back(index);
if(index==0){
int need=0,back=0;
for(int i=tmp.size()-1;i>=0;i--){
int id = tmp[i];
if(weight[id]>0)
back+=weight[id];
else{
if(back>(-weight[id]))
back+=weight[id];
else{
need+=(-weight[id])-back;
back=0;
}
}
}
if(need<minNeed){
minNeed = need;
minBack = back;
final = tmp;
}else if(need==minNeed&&back<minBack){
minBack=back;
final = tmp;
}
tmp.pop_back();
return;
}
for(int i=0;i<pre[index].size();i++)
dfs(pre[index][i]);
tmp.pop_back();
}
int main(){
fill(dis,dis+505,INF);
fill(e[0],e[0]+505*505,INF);
scanf("%d%d%d%d",&c,&n,&p,&m);
for(int i=1;i<=n;i++){
scanf("%d",&weight[i]);
weight[i] = weight[i]-c/2;
}
for(int i=0;i<m;i++){
int a,b,l;
scanf("%d%d%d",&a,&b,&l);
e[a][b] = e[b][a] = l;
}
dis[0] = 0;
for(int i=0;i<=n;i++){
int u=-1,min=INF;
for(int j=0;j<=n;j++){
if(visit[j]==false&&dis[j]<min){
u = j;
min = dis[j];
}
}
if(u==-1) break;
visit[u] = true;
for(int v=0;v<=n;v++){
if(visit[v]==false&&e[u][v]!=INF){
if(dis[u]+e[u][v]<dis[v]){
dis[v] = dis[u]+e[u][v];
pre[v].clear();
pre[v].push_back(u);
}else if(dis[u]+e[u][v]==dis[v]){
pre[v].push_back(u);
}
}
}
}
dfs(p);
printf("%d 0",minNeed);
for(int i=final.size()-2;i>=0;i--)
printf("->%d",final[i]);
printf(" %d",minBack);
return 0;
}
dfs中正着再遍历一遍模拟调整 考试的时候不要不敢写!!!!