这道题对我来说是一个新知识点,一开始用dijkstra解,只有25分,原因是不能用后面节点多出来的车辆弥补前面。
用dijkstra,25分
#include <iostream>
#include <cmath>
#include <stack>
using namespace std;
const int inf=99999999;
int vnum[520];
int road[520][520];
int dist[520];
int path[520];
int sent[520];
int take[520];
bool visit[520];
int main(){
int Cmax,N,S,M,s1,s2,bnum; //S是问题站点
scanf("%d %d %d %d",&Cmax,&N,&S,&M);
for(int i=1;i<=N;i++)
scanf("%d",&vnum[i]);
fill(road[0],road[0]+520*520,inf);
fill(dist,dist+520,inf);
int half=Cmax/2;
for(int i=0;i<M;i++){
scanf("%d %d %d",&s1,&s2,&bnum);
road[s1][s2]=bnum;
road[s2][s1]=bnum;
}
dist[0]=0;
path[0]=-1;
sent[0]=0;
take[0]=0;
while(1){
int mini=inf,u=-1;
for(int i=0;i<=N;i++){
if(dist[i]<mini&&visit[i]==false){
mini=dist[i];
u=i;
}
}
if(u==-1)
break;
visit[u]=true;
for(int j=1;j<=N;j++){
if(road[u][j]+dist[u]<dist[j]&&visit[j]==false){
dist[j]=road[u][j]+dist[u];
path[j]=u;
take[j]=take[u]+vnum[j]-half;
sent[j]=sent[u]+half-vnum[j];
}
else if(road[u][j]+dist[u]==dist[j]&&visit[j]==false){
if(abs(sent[j])>abs(sent[u]+half-vnum[j]) ){
sent[j]=sent[u]+half-vnum[j];
take[j]=take[u]+vnum[j]-half;
path[j]=u;
}
}
}
}
stack<int>zhan;
int h=S;
while(h!=0){
zhan.push(path[h]);
h=path[h];
}
if(sent[S]<0)
printf("0 ");
else
printf("%d ",sent[S]);
while(!zhan.empty()){
printf("%d->",zhan.top());
zhan.pop();
}
printf("%d ",S);
if(sent[S]<0)
printf("%d",abs(sent[S] ));
else
printf("0");
return 0;
}