Greedy Driver
题意
1.有个卡车司机叫爱德华,他现在任务是从1到n。
2.图上有m条有向边。
3.有p个点是加油站,他在加油站可以免费加油,加任意多的油,但是不能超过油箱上限C。
4有Q个点可以卖油,qi点,每桶油可以卖vi元,但是最多只能卖一次。
5.他想在完成任务的情况下赚尽可能多的钱。(如果不能到达n 输出-1)
6.问他最多能赚多少钱?
解
1.只能在一个点卖,则枚举出售点
2.预处理 dis1[qi]:1->qi最多留下的油量
3.预处理 dis2[qi]:qi->n至少需要的油量
4.ans=max(dis1[qi]-dis2[qi],ans)
5.这题同时存在正边和负边,dj是可以被卡的(虽然我过了),所以最好用spfa
具体代码
#include<bits/stdc++.h>
using namespace std;
const int M=1005;
typedef pair<int,int>P;
int n,m,TP,q;
int asdf,head[M],rhead[M],rasdf;
bool oil[M];
struct edge {
int to,nxt,cost;
} G[M*200],rG[M*200];
void add_edge(int a,int b,int c) {
G[++asdf].to=b;
G[asdf].nxt=head[a];
G[asdf].cost=c;
head[a]=asdf;
}
void radd_edge(int a,int b,int c) {
rG[++rasdf].to=b;
rG[rasdf].nxt=rhead[a];
rG[rasdf].cost=c;
rhead[a]=rasdf;
}
//只能在一个点卖油
//枚举在哪里卖油 用1->qi最多留下的油量 - qi->n至少需要的油量
int dis1[M],dis2[M];
bool vis[M];
void spfa(int S,int D) {
queue<int>Q;
for(int i=1; i<=n; i++) {
dis1[i]=-1;
vis[i]=0;
}
dis1[S]=D;
vis[S]=1;
Q.push(S);
while(!Q.empty()) {
int x=Q.front();
Q.pop();
vis[x]=0;
for(int i=head[x]; i; i=G[i].nxt) {
if(dis1[x]-G[i].cost<0)continue;
int y=G[i].to;
int cost=dis1[x]-G[i].cost;
if(oil[y])cost=TP;
if(dis1[y]<cost) {
dis1[y]=cost;
if(!vis[y]) {
Q.push(y);
}
}
}
}
}
void rspfa(int S,int D) {
queue<int>Q;
for(int i=1; i<=n; i++) {
dis2[i]=1e9;
vis[i]=0;
}
dis2[S]=D;
vis[S]=1;
Q.push(S);
while(!Q.empty()) {
int x=Q.front();
Q.pop();
for(int i=rhead[x]; i; i=rG[i].nxt) {
int y=rG[i].to;
if(rG[i].cost+dis2[x]>TP)continue;
int cost=dis2[x]+rG[i].cost;
if(oil[y])cost=0;
if(dis2[y]>cost) {
dis2[y]=cost;
if(!vis[y])Q.push(y);
}
}
}
}
int main() {
int a,b,c;
while(scanf("%d %d %d",&n,&m,&TP)==3) {
asdf=rasdf=0;
for(int i=1; i<=n; i++)head[i]=rhead[i]=oil[i]=0;
for(int i=1; i<=m; i++) {
scanf("%d %d %d",&a,&b,&c);
add_edge(a,b,c);
radd_edge(b,a,c);
}
scanf("%d",&q);
for(int i=1; i<=q; i++) {
scanf("%d",&a);
oil[a]=1;
}
spfa(1,TP);
rspfa(n,0);
scanf("%d",&q);
int ans=-1;
if(dis1[n]>=0)ans=0;
for(int i=1; i<=q; i++) {
scanf("%d %d",&a,&b);
if(dis1[a]==-1||dis2[a]==1e9)continue;
if(dis1[a]>=dis2[a]) {
ans=max(ans,(dis1[a]-dis2[a])*b);
}
}
printf("%d\n",ans);
}
return 0;
}