题意: 每个自行车车站的最大容量为一个偶数cmax,如果一个车站里面自行车的数量恰好为cmax / 2,那么称处于完美状态。如果一个车站容量是满的或者空的,控制中心(处于结点0处)就会携带或者从路上收集一定数量的自行车前往该车站,一路上会让所有的车站沿途都达到完美。现在给出cmax,车站的数量n,问题车站sp,m条边,还有距离,求最短路径。如果最短路径有多个,求能带的最少的自行车数目的那条。如果还是有很多条不同的路,那么就找一个从车站带回的自行车数目最少的(带回的时候是不调整的)
tip:DFS
#include<iostream>
#include<vector>
#include<algorithm>
#define INF 99999999
using namespace std;
struct station {
int tour,bike;
station() {}
station(int bike):bike(bike) {
tour=INF;
}
};
struct edge {
int to,length;
edge(int a,int b):to(a),length(b) {}
};
vector<edge>G[510];
station st[510];
int v[510];
vector<int>path;
vector<int>anspath;
int Sum=INF, Bring=INF,Take=INF;
int Cmax,N,Sp,M;
void dfs(int a,int sum,int bring,int take) {
path.push_back(a);
v[a]=1;
if(sum>Sum)return ;
if(take<0) {//只要与车站欠车就必须要从出发点带车过去
bring-=take;
take=0;
}
if(a==Sp) { //当为终点时判断是否为最优解
if(Sum>sum||(Sum==sum&&(Bring>bring||(Bring==bring&&Take>take)))) {
Sum=sum;
Bring=bring;
Take=take;
anspath=path;
}
return ;
}
for(auto it : G[a]) {
int to=it.to,length=it.length;
if(!v[to]) {
dfs(to,sum+length,bring,take+st[to].bike);
v[to]=0; //回溯
path.pop_back();
}
}
}
int main() {
scanf("%d%d%d%d",&Cmax,&N,&Sp,&M);
Cmax/=2;
int bike;
st[0]=station(0);
st[0].tour=0;
for(int i=1; i<=N; i++) {
scanf("%d",&bike);
st[i]=station(bike-Cmax); //bike为正则需带回,为负则需调配
}
int a,b,c;
for(int i=0; i<M; i++) {
scanf("%d%d%d",&a,&b,&c);
G[a].push_back(edge(b,c));
G[b].push_back(edge(a,c));
}
dfs(0,0,0,0);
printf("%d 0",Bring);
for(int i=1; i<anspath.size(); i++) {
printf("->%d",anspath[i]);
}
printf(" %d",Take);
return 0;
}