题意还有一些细节如下:
1. 同一站点同一轨道同一时刻最多只能发一列货车
2. 直接经过的列车不占用停车位
3. 每条轨道上不允许发生客车超过货车的情况,但同时出发或同时到达某站是合法的,而且不占用该站台的停车位,就算客车货车速度相同且同时出发仍然算合法的
4. 求能发出货车且在
Maxtime
M
a
x
t
i
m
e
内到达终点的最大值。
题中说到不能影响客车运行,也就是每列客车中途不停,到每个站的时间(同样也是从该站发车的时间)都是确定的。假设有一列客车在时刻 t t 从站出发,那么可以转化成一条限制,即 [t−Qi+Si,t−1] [ t − Q i + S i , t − 1 ] 这段时间内占用一条轨道(这段时间内不能向该轨道发货车),于是我们可以预处理出 fi,t f i , t 表示站 i i 在时间可用的轨道数。于是我们把每个站拆成 Maxtime M a x t i m e 个点,对于 (i,t) ( i , t ) 向 (i,t+1) ( i , t + 1 ) 连容量为 Pi P i 的边, (i,t) ( i , t ) 向 (i+1,t+Si) ( i + 1 , t + S i ) 连容量为 fi,t f i , t 的边,跑最大流就是答案。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define G(x,t) ((x)*(mxt+1)+(t))
#define N 60
#define M 210
using namespace std;
const int mxt=200;
const int inf=0x3f3f3f3f;
int tote,n,P[N],T[N],Q[N],S[N],fre[N][M],ans,con[N*M],nxt[N*M<<2],to[N*M<<2],f[N*M<<2],c[N*M<<2],ne[N*M],dl[N*M],ss,tt;
void ins(int x,int y,int cc)
{
to[++tote]=y;c[tote]=cc;nxt[tote]=con[x];con[x]=tote;
to[++tote]=x;c[tote]=0;nxt[tote]=con[y];con[y]=tote;
}
bool bfs()
{
memset(ne,0,sizeof(ne));
ne[ss]=1;dl[1]=ss;
for(int hd=1,tl=1,v=ss;hd<=tl;v=dl[++hd])
for(int p=con[v];p;p=nxt[p])
if(c[p]>f[p]&&!ne[to[p]])
ne[to[p]]=ne[v]+1,dl[++tl]=to[p];
return ne[tt]>0;
}
int dinic(int v,int flow)
{
if(v==tt) return flow;
if(ne[v]==-1) return 0;
int re=0;
for(int p=con[v];p&&flow;p=nxt[p])
if(c[p]>f[p]&&ne[to[p]]==ne[v]+1)
{
int o=dinic(to[p],min(flow,c[p]-f[p]));
f[p]+=o;f[p^1]-=o;
re+=o;flow-=o;
}
if(!re) ne[v]=-1;
return re;
}
int main()
{
scanf("%d",&n);
for(int i=0;i<=n;i++)
scanf("%d",&P[i]);
for(int i=0;i<=n;i++)
scanf("%d",&T[i]);
for(int i=0;i<=n;i++)
scanf("%d",&Q[i]);
for(int i=0;i<=n;i++)
scanf("%d",&S[i]);
for(int i=0;i<=n;i++)
for(int j=0;j<=200;j++)
fre[i][j]=T[i];
while(1)
{
int t,x;
scanf("%d%d",&t,&x);
if(t==-1&&x==-1) break;
for(int i=x;i<=n;t+=Q[i],i++)
for(int j=max(t+Q[i]-S[i]+1,0);j<t;j++)
fre[i][j]--;
}
ss=(n+1)*(mxt+1)+1,tt=(n+1)*(mxt+1)+2;
for(int j=0;j<=mxt;j++)
ins(ss,G(0,j),inf);
for(int i=0;i<=n;i++)
{
for(int j=0;j<=mxt-S[i];j++)
ins(G(i,j),i==n?tt:G(i+1,j+S[i]),fre[i][j]);
for(int j=0;j<mxt;j++)
ins(G(i,j),G(i,j+1),P[i]);
}
while(bfs()) ans+=dinic(ss,inf);//puts("!!!!");
printf("%d",ans);
return 0;
}