UVALive-3645 Objective: Berlin (最大流:时序模型)
题目大意:有n个城市,m条航班。已知每条航班的起点和终点,还有每条航班的载客量、出发时间、到达时间。并且要求在任何一个城市(起点、终点除外)都至少要有30分钟的中转时间,求起点到终点的最大客流量。
题目分析:将航线视作一个点,如果航线u能经过某城市中转到航线v,则从u连一条弧到v。构造好图之后拆点,将点u拆成u和u’,对于任意一个u,都连一条弧从u到u’,容量为航线上的载客量;对于节点u,从u’向u邻接的节点v连一条弧,容量为无穷大;增加源点s,从s向起点为出发点的航线u连一条弧,容量为无穷大,增加汇点t,从终点为目标点的航线v对应的v’向t连一条弧,容量也为无穷大。最后,答案就是最大流。
代码如下:
# include<iostream> # include<cstdio> # include<cmath> # include<string> # include<vector> # include<list> # include<set> # include<map> # include<queue> # include<cstring> # include<algorithm> using namespace std; # define LL long long # define REP(i,s,n) for(int i=s;i<n;++i) # define CL(a,b) memset(a,b,sizeof(a)) # define CLL(a,b,n) fill(a,a+n,b) const double inf=1e30; const int INF=1<<30; const int N=5050; //////////////////////////////////////// struct Edge { int fr,to,cap,fw; Edge(int _fr,int _to,int _cap,int _fw):fr(_fr),to(_to),cap(_cap),fw(_fw){} }; struct Dinic{ vector<Edge>edges; vector<int>G[N*2]; int d[N*2],vis[N*2],cur[N*2]; int s,t; void init(int n,int s,int t){ this->s=s,this->t=t; REP(i,0,n) G[i].clear(); edges.clear(); } void addEdge(int u,int v,int cap) { edges.push_back(Edge(u,v,cap,0)); edges.push_back(Edge(v,u,0,0)); int len=edges.size(); G[u].push_back(len-2); G[v].push_back(len-1); } bool BFS() { CL(vis,0); d[s]=0; vis[s]=1; queue<int>q; q.push(s); while(!q.empty()){ int x=q.front(); q.pop(); REP(i,0,G[x].size()){ Edge &e=edges[G[x][i]]; if(!vis[e.to]&&e.cap>e.fw){ d[e.to]=d[x]+1; vis[e.to]=1; q.push(e.to); } } } return vis[t]; } int DFS(int x,int a) { if(x==t||a==0) return a; int flow=0,f; for(int &i=cur[x];i<G[x].size();++i){ Edge &e=edges[G[x][i]]; if(d[e.to]==d[x]+1&&(f=DFS(e.to,min(a,e.cap-e.fw)))>0){ e.fw+=f; edges[G[x][i]^1].fw-=f; flow+=f; a-=f; if(a==0) break; } } return flow; } int MaxFlow() { int flow=0; while(BFS()){ CL(cur,0); flow+=DFS(s,INF); } return flow; } }; Dinic dinic; //////////////////////////////////////// struct Flight { string p,q; int a,st,et; }; Flight fl[N*2]; int n,m; string p,q; int f(int a,int b) { int t1=(a/100)*60+a%100; int t2=(b/100)*60+b%100; return t1-t2; } int main() { int limit; while(~scanf("%d",&n)) { cin>>p>>q>>limit; scanf("%d",&m); dinic.init(m*2+2,0,m*2+1); REP(i,1,m+1) cin>>fl[i].p>>fl[i].q>>fl[i].a>>fl[i].st>>fl[i].et; REP(i,1,m+1){ if(fl[i].p==p) dinic.addEdge(0,i*2-1,INF); if(fl[i].q==q&&fl[i].et<=limit) dinic.addEdge(i*2,m*2+1,INF); dinic.addEdge(i*2-1,i*2,fl[i].a); REP(j,1,m+1){ if(i==j) continue; if(fl[i].q==fl[j].p&&f(fl[j].st,fl[i].et)>=30) dinic.addEdge(i*2,j*2-1,INF); } } printf("%d\n",dinic.MaxFlow()); } return 0; }