思路:先用dijk求出最短路,利用pre[v]保存成另一个图,再用dfs深搜这个新图
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <stack>
using namespace std;
const int inf=2100000000;
int Cmax,N,ed,M;
int w[1005]={0};
int g[1005][1005];
int dis[1005];
int book[1005]={0};//记录dis的记录情况
vector<int> pre[1005];
void init()
{
for(int i=0;i<1005;i++)
for(int j=0;j<1005;j++)
{
g[i][j]=inf;
g[j][i]=inf;
}
for(int i=0;i<1005;i++)
{
dis[i]=inf;
}
}
void dijk()
{
for(int i=0;i<=N;i++)
{
if(g[0][i]!=inf)
{
dis[i]=g[0][i];
pre[i].push_back(0);
}
}
dis[0]=0;
book[0]=1;
for(int i=0;i<N;i++)
{
int u=-1;
int minn=inf;
for(int i=0;i<=N;i++)
{
if(book[i]==0&&dis[i]<minn)//找到dis没有记录过的最小点
{
minn=dis[i];
u=i;
}
}
if(u==-1)//剩下的点都不连通
return;
book[u]=1;
for(int v=0;v<=N;v++)
{
if(book[v]==0&&g[u][v]!=inf)
{
if(dis[u]+g[u][v]<dis[v])
{
dis[v]=dis[u]+g[u][v];
pre[v].clear();
pre[v].push_back(u);
}
else if(dis[u]+g[u][v]==dis[v])
{
pre[v].push_back(u);
}
}
}
}
}
vector<int> ans,v;
int minneed=inf;
int minstore=inf;
void dfs(int id)
{
if(id==0)
{
v.push_back(id);
int need=0;
int store=0;
for(int i=v.size()-1;i>=0;i--)
{
if(w[v[i]]>0)
{
store+=w[v[i]];
}
else if(w[v[i]]<0)
{
if(store<=abs(w[v[i]]))
{
need+=abs(w[v[i]])-store;
store=0;
}
else
{
store-=abs(w[v[i]]);
}
}
}
if(need<minneed)
{
minneed=need;
minstore=store;
ans=v;
}
else if(need==minneed&&store<minstore)
{
minneed=need;
minstore=store;
ans=v;
}
v.pop_back();
return;
}
v.push_back(id);
for(int i=0;i<pre[id].size();i++)
{
dfs(pre[id][i]);
}
v.pop_back();
}
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d %d %d %d",&Cmax,&N,&ed,&M);
init();
for(int i=1;i<=N;i++)
{
int t;
scanf("%d",&t);
w[i]=t-Cmax/2;
}
for(int i=0;i<M;i++)
{
int t1,t2,t;
scanf("%d %d %d",&t1,&t2,&t);
g[t1][t2]=t;
g[t2][t1]=t;
}
dijk();
dfs(ed);
printf("%d ",minneed);
for(int i=ans.size()-1;i>=0;i--)
{
printf("%d",ans[i]);
if(i!=0)
printf("->");
}
printf(" %d",minstore);
return 0;
}