UVa1161 Objective: Berlin(最大流)
题目
Source
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3602
Description
The administration of a well-known football team has made a study about the lack of support in international away games. This study has concluded that the only reason for this lack of support is the difficulty in organizing the travel arrangements. To help solving this problem, the administration has asked you to build a program that computes the maximum number of people that can fly from a departure city to a destination city, using the available places in regular flights in a given day, and arriving at or before a given time. When traveling from one city to another, a person may make multiple transfers. Each transfer is, at least, 30 minutes long, i.e., the departure time should be, at least 30 minutes after the arrival time. Given a set of flights for a single day and the latest arrival time, your program should compute the maximum number of persons that can fly, directly or indirectly, from departure city to a destination city, arriving at or before the latest arrival time.
Input
The input will contain several test cases, each of them as described below. Consecutive test cases are separated by a single blank line. The first line contains an integer (smaller or equal to 150) indicating the number of cities that have flight connections. The second line contains a string indicating the city of departure. The third line contains a string indicating the destination city. The fourth line contains the latest arrival time, in the format HHMM, where HH is the hour in the day (from 00 to 23) and MM is the minute in the hour (from 00 to 59). The fifth line contains an integer N (smaller or equal to 5000), with the number of existing flights. Each of the following N lines contains the info for each flight. Each such line contains two strings and three integers, separated by blank spaces, O E C D A, where O and E are, respectively, the origin and destination of a flight, C is the number of available places in the flight (from 0 to 300), and D and A are the departure and arrival times in the previously defined format HHMM. All flights start and end in the same day. City names may have up to 8 characters.
Output
For each test case, the output must follow the description below.
The output consists of one single line with an integer stating the maximum number of people that can fly from the origin to the destination city, using the given flights and arriving at or before the given latest arrival time.
Sample Input
4
lisbon
berlin
1500
9
lisbon london 6 1000 1100
london lisbon 6 1130 1230
lisbon paris 5 1000 1100
paris lisbon 4 1130 1230
london paris 1 1130 1300
london berlin 2 1340 1510
berlin london 2 1300 1430
paris berlin 10 1330 1500
berlin paris 9 1300 1430
Sample Output
6
分析
题目大概说有n个城市和m条航线,每条航线都是从某一时刻某一城市出发在某一时刻到达某一城市,且各条航线都有最多人数的限制。现在已知出发城市和目的地城市以及一个最终的时刻,问最多有多少人能在最终时刻前到达目的地。
这题自然会去想把城市看成点,航线看成边。这样的话城市需要按照时间拆点24*60*100=144000,太多了。。然而事实上有连边的点最多只会有2*m个,即10000个,其他10多W都是摆设,所以其实也OK吧。
这题的正解是:
- 把航线看成点,并且拆成两点x和x',x表示航线开始,另一点x'表示航线结束;
- 新建源点汇点,源点向所有从出发城市是起始城市的航线x连容量INF的边,所有到达城市是目的地且到达时间在最终时刻之前的航线x'向汇点连容量INF的边;
- 所有航线,x向x'连容量为航线限制人数的边,这样就表示航线从开始到结束最多能流过的人数;
- 对于所有的A航线和B航线,满足A航线到达城市为B航线出发城市 且 A航线到达时刻+30分钟在B航线开始时刻之前,由A'到B连容量INF的边,这样就表示A航线结束后可以起身开始进行B航线;
- 跑最大流就是结果了。
其实,这个解法也能看成是把城市按时间拆点并离散化。
不过没想到真的是10000个点去跑网络流。。另外,思维不要局限,图中的点和边可以是各种东西。。要大胆建图跑网络流。。
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 11111
#define MAXM 2222222 struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NE,NV;
int head[MAXN]; void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=0;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=0; edge[NE].flow=0;
edge[NE].next=head[v]; head[v]=NE++;
} int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-1,sizeof(level));
memset(gap,0,sizeof(gap));
level[vt]=0;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-1) continue;
level[v]=level[u]+1;
gap[level[v]]++;
que.push(v);
}
}
} int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-1,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=0,aug=INF;
gap[0]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+1){
flag=true;
pre[v]=u;
u=v;
//aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^1].flow-=aug;
}
//aug=-1;
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-1; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==0) break;
level[u]=minlevel+1;
gap[level[u]]++;
u=pre[u];
}
return flow;
} int covert_time(int t){
return t/100*60+t%100;
} string city[111]; string from[5555],to[5555];
int cap[5555],s[5555],t[5555]; int main(){
int n,m;
while(cin>>n){
string s_city,t_city;
cin>>s_city>>t_city; int deadline; cin>>deadline;
deadline=covert_time(deadline); cin>>m;
for(int i=1; i<=m; ++i){
cin>>from[i]>>to[i]>>cap[i]>>s[i]>>t[i];
s[i]=covert_time(s[i]);
t[i]=covert_time(t[i]);
} vs=0; vt=m*2+1; NV=vt+1; NE=0;
memset(head,-1,sizeof(head));
for(int i=1; i<=m; ++i){
if(from[i]==s_city) addEdge(vs,i,INF);
if(to[i]==t_city && t[i]<=deadline) addEdge(i+m,vt,INF);
addEdge(i,i+m,cap[i]);
}
for(int i=1; i<=m; ++i){
for(int j=1; j<=m; ++j){
if(i==j) continue;
if(to[i]==from[j] && t[i]+30<=s[j]) addEdge(i+m,j,INF);
}
}
printf("%d\n",ISAP());
}
return 0;
}
UVa1161 Objective: Berlin(最大流)的更多相关文章
- UVALive 3645 Objective: Berlin(最大流 :时序模型)
题意:已知n(n <= 150)个城市和m(m <= 5000)个航班,每个航班有出发地.到达地.乘坐人数.起飞时间和降落时间(时间用时和分表示),求从一个指定城市出发,去往另一个指定城市 ...
- UVaLive 3645 Objective: Berlin (最大流)
题意:有n个城市,m条航班.已知每条航班的起点和终点,还有每条航班的载客量.出发时间.到达时间.并且要求在任何一个城市(起点.终点除外)都至少要有30分钟的中转时间,求起点到终点的最大客流量. 析:把 ...
- UVa 1161 Objective: Berlin (最大流)
题意:给定一些航班,每个航班有人数,和起始终止时间,每次转机要花半小时,问限制时间内最多能有多少人从起始城市到终点城市. 析:差不多是裸板网络流的最大流问题,把每个航班都拆成两个点,这两个点之间连接一 ...
- UVA - 1161 Objective: Berlin(最大流+时序模型)
题目大意:有n个城市m条航线.给出每条航线的出发地,目的地,座位数,起飞时间和到达时间(所给形式为HHMM.记得转化),再给出城市A和B.和到达城市B的最晚时间.如今问一天内最多有多少人能从A飞到B, ...
- UVALive-3645 Objective: Berlin (最大流:时序模型)
题目大意:有n个城市,m条航班.已知每条航班的起点和终点,还有每条航班的载客量.出发时间.到达时间.并且要求在任何一个城市(起点.终点除外)都至少要有30分钟的中转时间,求起点到终点的最大客流量. 题 ...
- UVALIVE 3645 Objective: Berlin
最大流 .以航班为节点进行最大流. 容量限制进行拆点. 如果时间地点满足可以建一条边. 具体看代码.变量名被修改过了.一开始的变量名可能比较容易看懂 但CE了.可能与库里的变量重复了. AC代码 #i ...
- Automake
Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...
- Objective-C的IO流
- HDU4309-Seikimatsu Occult Tonneru(最大流)
Seikimatsu Occult Tonneru Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
随机推荐
- c++ 子类调用父类构造方法 调用父类方法 类声明与实现分离
Person.h #pragma once #include "stdafx.h" #include<iostream> class Person { private: ...
- JqueryEasyUI 解决IE下datagrid无法刷新的问题 分类: JavaScript JqueryEasyUI 2014-09-20 10:05 510人阅读 评论(1) 收藏
问题描述: 在使用JqueryEasyUI 时,发现在IE下$('#table').datagrid('reload');无效,数据并没有被刷新,究其原因,是因为刷新时,datagrid请求的url没 ...
- PowerDesigner连接Oracle数据库生成数据模型【本地连接方式】
步骤1:选择数据库 步骤2:选择要连接的数据库的版本 步骤3:新建数据库连接 步骤4:提供3种连接数据库方式(在此选择第3种),并且点击配置按钮,进行下一步 步骤5:点击此按钮,填 ...
- C# 令某个窗体可跟着鼠标移动
/// <summary> /// 使窗口的中的指定控件支持运行时移动 /// TODO:运行时缩放 /// </summary> public class ControlMo ...
- jquery mobile 转场闪屏的解决
jqm转场闪屏是用phonegap生成apk非常容易遇到的问题,暂时貌似还是没有完美的解决方案,网上暂时有一些方案,个人都尝试了一下发现还是改背景比较有效,总结如下: 改变默认css文件: .ui- ...
- VS2012 配置 OpenCV3.0
VS2012 配置 opencv3.0,相比之前的版本,3.0的配置简单了好多. 通过配置属性文件,可以做到一次配置,重复使用! 根据文章的操作在 win7 64bit VS2012 下成功配置 op ...
- GitHub 使用教程图文详解(转)
大纲: 一.前言 二.GitHub简介 三.注册GitHub账号 四.配置GitHub 五.使用GitHub 六.参与GitHub中其它开源项目 七.总结 注,GitHub官网:https://git ...
- 程序员应该是使用git
我来梳理下我想用git做的事情应该拥有那些功能: 本地的git命令以及图形界面,好让我在没有联网的时候创建git版本控制记录历史功能 一个github账号,好让我可以把本地的git仓库同步到那里 功能 ...
- Eclipse的详细安装步骤
第一种:这个方法是在线安装的 第二种:下载完整免安装包 首先打开网址:http://www.eclipse.org/ 然后在这里我就选择64位的安装,就以安装安卓开发的举例: 然后下载即可:
- javascript中时间的手动创建date的方式
new Date("month dd,yyyy hh:mm:ss"); new Date("month dd,yyyy"); new Date(yyyy,mth ...