LA 3645:Objective: Berlin
传送门:https://vjudge.net/problem/UVALive-3645
解析:
白书题意不翻译全,真是坑人……
大概意思就是有\(n\)个城市(\(n\leq150\)), \(m\)个航班(\(m\leq5000\)),给出每个航班的起飞和降落时间,最大载客量,坐完一次航班要等30min才能继续坐,求从城市A到城市B在某一时刻之前能最多运多少乘客。
我们可以把它看成一个简单的时间模型,先离散化时刻,对于每座城市的每一个时刻都建立一个结点,转机的30min直接加到结束时间上,航班就把两座城市对应的时刻连边,容量为载客量,每个城市的时刻向下一时刻连边,容量为INF(表示乘客在此城市等待),跑出最大流即可。
但这个题恶心的地方来了:这个做法会TLE!的确,我们连的很多INF的边都是冗余的,造成了时间上的浪费。
所以就有了第二种做法:我们把航班看成点,如果乘客在坐完航班p还能赶上航班q则连边,容量为INF,航班加上一个结点容量,为载客量,因为能转乘的航班很有限(每个航班至少要飞30min),所以这个做法是完全可行的。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#define rep(i,x,y) for (int i=x;i<=y;i++)
#define dep(i,y,x) for (int i=y;i>=x;i--)
#define sz(x) (int)(x.size())
using namespace std;
typedef long long LL;
const int maxn=10000+21;
const int INF=(1<<30);
struct Edge{
 int u,v,cap,flow,next;
} E[maxn*100];
int T,n,final,m,x[maxn],y[maxn],tx[maxn],ty[maxn],dis[maxn],ns,nt,k,size,s,t;
int last[maxn],Esize,mini,p,F[maxn],cur[maxn],num[maxn],d[maxn],flow,L,R,Q[maxn];
string sx,sy,from,to;
bool mark,vis[maxn];
void addedge(int x,int y,int cap)
{
 E[++Esize]=(Edge){x,y,cap,0,last[x]},last[x]=Esize;
 E[++Esize]=(Edge){y,x,0,0,last[y]},last[y]=Esize;
}
void init()
{
  map<string,int> M;
  size=0,Esize=1;
  memset(last,0,sizeof(last));
	
  final=(final/100)*60+(final%100);
 
  if (!M[from]) M[from]=++size;
  if (!M[to]) M[to]=++size;
  
  ns=M[from],nt=M[to];
  
  rep(i,1,m)
  {
   cin >> sx >> sy >> dis[i] >> tx[i] >> ty[i];
   
   tx[i]=(tx[i]/100)*60+(tx[i]%100),ty[i]=(ty[i]/100)*60+(ty[i]%100);
   
   if (!M[sx]) M[sx]=++size;
   if (!M[sy]) M[sy]=++size;
   
   x[i]=M[sx],y[i]=M[sy];
  }
 
 s=1,size=t=2*m+2;
 
 rep(i,1,m) addedge(i<<1,(i<<1)|1,dis[i]);
 
 rep(i,1,m) if (x[i]==ns) addedge(s,(i<<1),INF);
 rep(i,1,m) if ((y[i]==nt)&&(ty[i]<=final)) addedge((i<<1)|1,t,INF);
	
 rep(i,1,m)
  rep(j,1,m)
   if ((y[i]==x[j])&&((ty[i]+30)<=tx[j])) addedge((i<<1)|1,(j<<1),INF);
}
void BFS()
{
 memset(vis,0,sizeof(vis)),vis[t]=1;
 
 L=R=1,Q[1]=t,d[t]=0;
 while (L<=R)
 {
  p=Q[L],L++;
  for (int i=last[p];i;i=E[i].next)
   if (!vis[E[i].v]) Q[++R]=E[i].v,d[E[i].v]=d[p]+1,vis[E[i].v]=1;
 }
}
int calc()
{
 k=INF,p=t;
 while (p!=s) k=min(k,E[F[p]].cap-E[F[p]].flow),p=E[F[p]].u;
 
 p=t;
 while (p!=s) E[F[p]].flow+=k,E[F[p]^1].flow-=k,p=E[F[p]].u;
 
 return k;
}
int Maxflow()
{
 flow=0,BFS();
 
 memset(num,0,sizeof(num));
 rep(i,1,size) num[d[i]]++;
 
 rep(i,1,size) cur[i]=last[i];
 p=s;
 
 while (d[s]<size)
 {
  if (p==t) flow+=calc(),p=s;
 
  mark=0;
  for (int i=cur[p];i;i=E[i].next)
   if ((E[i].cap>E[i].flow)&&(d[p]==d[E[i].v]+1))
   {
    mark=1;
	cur[p]=i,p=E[i].v,F[p]=i;
	break;
   }
  
  if (!mark)
  {
   mini=size-1;
   for (int i=last[p];i;i=E[i].next)
	if (E[i].cap>E[i].flow) mini=min(mini,d[E[i].v]);
   
   if ((--num[d[p]])==0) break;
   d[p]=mini+1,num[d[p]]++;
   
   cur[p]=last[p];
   if (p!=s) p=E[F[p]].u;
  }
 }
 return flow;
}
int main()
{
 while (cin >> n)
 {
  cin >> from >> to >> final >> m; 
  init();
	
  cout << Maxflow() << endl;
 }
 return 0;
}
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号