#include<bits/stdc++.h>
using namespace std;
const int MAXN=502;
const int INF=1000000000;
int weight[MAXN];
int G[MAXN][MAXN];
bool vis[MAXN]={false};
int d[MAXN]={};
int cm,n,sp,m;
vector<int> pre[MAXN];
vector<int> temppath,bestpath;
int minsend=INF,minback=INF;
void dij(int v){
fill(d,d+MAXN,INF);
d[v]=0;
for(int i=0;i<=n;i++){
int k=-1;int MIN=INF;
for(int j=0;j<=n;j++){
if(vis[j]==false&&d[j]<MIN){
k=j;
MIN=d[j];
}
}
if(k==-1) return;
vis[k]=true;
for(int j=0;j<=n;j++){
if(vis[j]==false&&G[k][j]!=INF){
if(d[k]+G[k][j]<d[j]){
d[j]=d[k]+G[k][j];
pre[j].clear();
pre[j].push_back(k);
}else if(d[k]+G[k][j]==d[j]){
pre[j].push_back(k);
}
}
}
}
}
void dfs(int v){
if(v==0){
temppath.push_back(v);
int send=0,back=0;
for(int i=temppath.size()-1;i>=0;i--){
int id=temppath[i];
if(weight[id]>0){
back+=weight[id];
}else{
if(back+weight[id]>0){
back+=weight[id];
}else{
send+=abs(weight[id])-back;
back=0;
}
}
}
if(send<minsend){
minsend=send;
minback=back;
bestpath=temppath;
}else if(send==minsend&&back<minback){
minback=back;
bestpath=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()
{
freopen("in.txt","r",stdin);
cin>>cm>>n>>sp>>m;
for(int i=1;i<=n;i++){
cin>>weight[i];
weight[i]-=(cm/2);
}
fill(G[0],G[0]+MAXN*MAXN,INF);
for(int i=0;i<m;i++){
int start,end,len;
cin>>start>>end>>len;
G[start][end]=len;
G[end][start]=len;
}
dij(0);dfs(sp);
cout<<minsend<<' ';
for(int i=bestpath.size()-1;i>=0;i--){
if(i==bestpath.size()-1) cout<<bestpath[i];
else cout<<"->"<<bestpath[i];
}
cout<<' '<<minback;
return 0;
}
dij+dfs可以AC;
下面单纯的dij得到20分;
#include<bits/stdc++.h>
using namespace std;
const int MAXN=502;
const int INF=1000000000;
int weight[MAXN];
int G[MAXN][MAXN];
bool vis[MAXN]={false};
int dis[MAXN]={};
int cm,n,sp,m;
int w[MAXN]={};
int path[MAXN];
void dij(int v){
fill(dis,dis+MAXN,INF);
dis[v]=0;
for(int i=0;i<MAXN;i++) path[i]=i;
weight[v]=0;
for(int i=0;i<=n;i++){
int k=-1;int MIN=INF;
for(int j=0;j<=n;j++){
if(vis[j]==false&&dis[j]<MIN){
k=j;
MIN=dis[j];
}
}
if(k==-1) return;
vis[k]=true;
for(int j=0;j<=n;j++){
if(vis[j]==false&&G[k][j]!=INF){
if(dis[k]+G[k][j]<dis[j]){
dis[j]=dis[k]+G[k][j];
path[j]=k;
w[j]=w[k]+(weight[j]-cm/2);
}else if(dis[k]+G[k][j]==dis[j]){
if(w[j]<w[k]+(weight[j]-cm/2)){
w[j]=w[k]+(weight[j]-cm/2);
path[j]=k;
}
}
}
}
}
}
void dfs(int start,int end){
if(start==end){
printf("%d",start);
return;
}
dfs(start,path[end]);
printf("->%d",end);
}
int main()
{
freopen("in.txt","r",stdin);
cin>>cm>>n>>sp>>m;
for(int i=1;i<=n;i++){
cin>>weight[i];
}
fill(G[0],G[0]+MAXN*MAXN,INF);
for(int i=0;i<m;i++){
int start,end,len;cin>>start>>end>>len;
G[start][end]=len;
G[end][start]=len;
}
dij(0);
int send=0,back=0;
if(w[sp]<0){
send=abs(w[sp]);
}else{
back=w[sp];
}
cout<<send<<' ';
dfs(0,sp);
cout<<' '<<back;
return 0;
}
dij代码比较简单,dij+dfs差不多多出来了30行代码,但是dij+dfs适用范围比较广...