题目地址:http://pat.zju.edu.cn/contests/pat-a-practise/1018
分析:本题涉及图,求最短距离的同时计算代价(自行车带出去的最少,带回来的也最少)用深搜,同时使用vector记录路径
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#define vmax 0x7fffffff
using namespace std;
int dis[501][501];
int curbike[501];
int cmax,n,sp,m;
bool visit[501];
vector<int> path;
vector<int> rpath;
int rBike=vmax;
int rBackBike=0;
int rDis=vmax;
void dfs(int station){
for(int i=1;i<=n;i++){
if(!visit[i]&&dis[station][i]!=-1){
visit[i]=true;
path.push_back(i);
if(i==sp){
int t=0;
for(int k=1;k<path.size();k++){
t+=dis[path[k]][path[k-1]];
}
t+=dis[0][path[0]];
if(t<=rDis){
rDis=t;
int available=0;
int bringBike=0;
for(int k=0;k<path.size();k++){//此处一定不能直接用计算总量
if(curbike[path[k]]<cmax/2){
if(available<cmax/2-curbike[path[k]]){
bringBike+=cmax/2-curbike[path[k]]-available,available=0;
}
else{
available-=cmax/2-curbike[path[k]];
}
}
else{
available+=curbike[path[k]]-cmax/2;
}
}
if(t<rDis||(t==rDis&&bringBike<rBike)||(t==rDis&&bringBike==rBike&&rBackBike>available)){//此处判断条件一定注意,测试点56789
rBike=bringBike,rBackBike=available;
rpath.clear(),rpath=path;
}
}
path.pop_back();
visit[i]=false;
return;
}
dfs(i);
visit[i]=false;
path.pop_back();
}
}
}
int main(){
//freopen("C:\\Users\\Devon\\Desktop\\input.txt","r",stdin);
cin>>cmax>>n>>sp>>m;
memset(dis,-1,sizeof(dis));
for(int i=1;i<=n;i++)
cin>>curbike[i];
for(int i=0;i<m;i++){
int t1,t2,t3;
cin>>t1>>t2>>t3;
dis[t1][t2]=t3;
dis[t2][t1]=t3;
}
for(int i=1;i<=n;i++)
visit[i]=false;
visit[0]=true;
path.clear();
rpath.clear();
dfs(0);
cout<<rBike;
cout<<" ";
cout<<0;
for(int i=0;i<rpath.size();i++){
cout<<"->"<<rpath[i];
}
cout<<" ";
cout<<rBackBike;
return 0;
}