1. 程式人生 > >[聯合集訓6-19] 新幹線 猜測題意+拆點網路流

[聯合集訓6-19] 新幹線 猜測題意+拆點網路流

題意還有一些細節如下:
1. 同一站點同一軌道同一時刻最多隻能發一列貨車
2. 直接經過的列車不佔用停車位
3. 每條軌道上不允許發生客車超過貨車的情況,但同時出發或同時到達某站是合法的,而且不佔用該站臺的停車位,就算客車貨車速度相同且同時出發仍然算合法的
4. 求能發出貨車且在Maxtime內到達終點的最大值。

題中說到不能影響客車執行,也就是每列客車中途不停,到每個站的時間(同樣也是從該站發車的時間)都是確定的。假設有一列客車在時刻ti站出發,那麼可以轉化成一條限制,即[tQi+Si,t1]這段時間內佔用一條軌道(這段時間內不能向該軌道發貨車),於是我們可以預處理出

fi,t表示站i在時間t可用的軌道數。於是我們把每個站拆成Maxtime個點,對於(i,t)(i,t+1)連容量為Pi的邊,(i,t)(i+1,t+Si)連容量為fi,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; }