Dijkstra+DFS解决,难点在handle函数计算路径的Need 和Remain
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXN=510;
const int INF=0x3fffffff;
int G[MAXN][MAXN];
int vis[MAXN]={false};
int d[MAXN];
int weight[MAXN];
vector<int> pre[MAXN];
vector<int> path,tempPath;
int C,N,S,M;
void Dijkstra(int s){
fill(d,d+MAXN,INF);
d[s]=0;
for(int i=0;i<=N;i++){
int MIN=INF,u=-1;
for(int j=0;j<=N;j++){
if(vis[j]==false&&d[j]<MIN){
MIN=d[j];
u=j;
}
}
if(u==-1)return ;
vis[u]=true;
for(int v=0;v<=N;v++){
if(G[u][v]!=INF&&vis[v]==false){
if(d[u]+G[u][v]<d[v]){
d[v]=d[u]+G[u][v];
pre[v].clear();
pre[v].push_back(u);
}else if(d[u]+G[u][v]==d[v]){
pre[v].push_back(u);
}
}
}
}
}
void handle(vector<int>path,int& need,int &remain){
for(int i=path.size()-2;i>=0;i--){
int id=path[i];
if(weight[id]>0){
remain+=weight[id];
}else {
if(remain>abs(weight[id])){
remain-=abs(weight[id]);
}else{
need+=abs(weight[id])-remain;
remain=0;
}
}
}
}
int needMIN=INF,remainMIN=INF;
void DFS(int v){
if(v==0){
tempPath.push_back(v);
int need=0,remain=0;
handle(tempPath,need,remain);
if(need<needMIN){
needMIN=need;
remainMIN=remain;
path=tempPath;
}else if(need==needMIN&&remain<remainMIN){
remainMIN=remain;
path=tempPath;
}
tempPath.pop_back();
return;
}
tempPath.push_back(v);
for(int i=0;i<pre[v].size();i++){
DFS(pre[v][i]);
}
tempPath.pop_back();
}
int main(){
fill(G[0],G[0]+MAXN*MAXN,INF);
scanf("%d%d%d%d",&C,&N,&S,&M);
for(int i=1;i<=N;i++){
int w;
scanf("%d",&w);
weight[i]=w-C/2;
}
for(int i=0;i<M;i++){
int u,v,dis;
scanf("%d%d%d",&u,&v,&dis);
G[u][v]=G[v][u]=dis;
}
Dijkstra(0);
DFS(S);
printf("%d ",needMIN);
for(int i=path.size()-1;i>=0;i--){
printf("%d",path[i]);
if(i>0)printf("->");
}
printf(" %d\n",remainMIN);
return 0;
}