ZOJ-3794 Greedy Driver Shortest Path
First, run 1 as the shortest path of the start point. Note that if the relaxation process reaches the gas station, dis = 0, and dis cannot be greater than C at any time on the road, determine whether dis [n] is <= C to determine whether there is no solution.
Then, create a reverse graph and run N again as the starting point's shortest path. In this way, the shortest path from each point to n can be obtained.
For every city that can be traded, C-dis1 [I]-dis2 [I] is the oil that can be sold out.
#include
#include
#include
#include
#include
#include#include
using namespace std;#define maxn 5005#define maxm 200005struct node{ int v,w,next;}edge[maxm];int head[maxn+maxn];bool in[maxn];int dis[maxn];bool fuel[maxn];int money[maxn];int a,b,c,n,m,id;int co;void add(int a,int b,int c){ edge[id].v=b; edge[id].w=c; edge[id].next=head[a]; head[a]=id++;}void init(){ memset(fuel,0,sizeof(int)*(n+1)); memset(head,-1,sizeof(int)*(n+1)); memset(money,0,sizeof(int)*(n+1)); id=0;}void SPFA(int st){ queue
Q; memset(in,0,sizeof(int)*(n+1)); memset(dis,0x3f,sizeof(int)*(n+1)); Q.push(st); in[st]=1; dis[st]=0; int tmp; while(!Q.empty()) { tmp=Q.front();Q.pop(); in[tmp]=0; for(int i=head[tmp];i!=-1;i=edge[i].next) { if(dis[edge[i].v]>dis[tmp]+edge[i].w&&dis[tmp]+edge[i].w<=co) { dis[edge[i].v]=dis[tmp]+edge[i].w; if(fuel[edge[i].v]) dis[edge[i].v]=0; if(!in[edge[i].v]) { in[edge[i].v]=1; Q.push(edge[i].v); } } } }}int save[maxm][3];int savedis[maxn];int main(){ int a,b,d; while(~scanf("%d%d%d",&n,&m,&co)) { init(); for(int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&d); save[i][0]=a; save[i][1]=b; save[i][2]=d; add(a,b,d); } scanf("%d",&a); for(int i=1;i<=a;i++) { scanf("%d",&b); fuel[b]=1; } scanf("%d",&a); for(int i=1;i<=a;i++) { scanf("%d%d",&b,&d); money[b]=d; } SPFA(1); if(dis[n]>co) puts("-1"); else { int ans=0; id=0; memset(head,-1,sizeof(head)); memcpy(savedis,dis,sizeof(dis)); for(int i=1;i<=m;i++) add(save[i][1],save[i][0],save[i][2]); SPFA(n); for(int i=1;i<=n;i++) { if(money[i]&&dis[i]<=co&&savedis[i]<=co) { ans=max(ans,(co-savedis[i]-dis[i])*money[i]); } } printf("%d\n",ans); } } return 0;}/*5 6 101 2 41 4 14 3 12 5 14 5 23 2 11312 2*/