Dijkstra+DFS问题,本题涉及到的知识点有,最短路径统计,最短路径记录,路径优化
坑点如下
1,本题首先将所有最短路径统计出来。利用verctor容器
2,利用DFS递归的方法,用vector容器temp将最短路径存储,并进行优化比较,总结出所求路径
3,将bike数目整体减去cmax/2从而简化处理。
4,注意点,在dijkstra中将d数初始化,在主函数中将G数组初始化,dijksra参数为初始结点,DFS参数为终止结点。
代码如下
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
const int maxn=510;
const int INF=0x3fffffff;
int G[maxn][maxn];
bool vis[maxn]={false};
int d[maxn];
int minneed=INF,minhave=INF;
int bike[maxn];
int num[maxn];
int cmax,n,sp,m;
struct Node{
int need;
int nowhave;
vector<int>path;
}node[maxn];
vector<int>pre[maxn],temp,path,ans;
void dijkstra(int s){
fill(d,d+maxn,INF);
d[s]=0;
num[s]=1;
for(int i=0;i<=n;i++){
int u=-1,MIN=INF;
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(vis[v]==false&&G[u][v]!=INF){
if(d[u]+G[u][v]<d[v]){
d[v]=d[u]+G[u][v];
num[v]=num[u];
pre[v].clear();
pre[v].push_back(u);
}
else if(d[u]+G[u][v]==d[v])
{ pre[v].push_back(u);
num[v]+=num[u];
}
}
}
}
}
void DFS(int v){
if(v==0){
temp.push_back(v);
int neednow=0,havenow=0;
for(int i=temp.size()-1;i>=0;i--){
if(bike[temp[i]]>=0){
havenow+=bike[temp[i]];
}
else
{
if(havenow>=abs(bike[temp[i]]))
{havenow-=abs(bike[temp[i]]);}
else
{
neednow+=(abs(bike[temp[i]])-havenow);
havenow=0;
}
}
}
if(neednow<minneed){minneed=neednow;
minhave=havenow;
ans.clear();
ans=temp;}
else if(neednow==minneed){
if(havenow<minhave)
{
minhave=havenow;
ans.clear();
ans=temp;
}
}
temp.pop_back();
return;
}
temp.push_back(v);
for(int i=0;i<pre[v].size();i++)
{DFS(pre[v][i]);}
temp.pop_back();
}
int main(){
scanf("%d%d%d%d",&cmax,&n,&sp,&m);
int num;
fill(G[0],G[0]+maxn*maxn,INF);
for(int i=1;i<=n;i++){
scanf("%d",&num);
bike[i]=num-cmax/2;
}
for(int i=0;i<m;i++){
int s1,s2,dis;
scanf("%d%d%d",&s1,&s2,&dis);
G[s1][s2]=G[s2][s1]=dis;
}
dijkstra(0);
DFS(sp);
printf("%d ",minneed);
for(int i=ans.size()-1;i>=0;i--){
printf("%d",ans[i]);
if(i!=0)printf("->");
}
printf(" %d",minhave);
}