题意

你在一座城市里负责一个大型活动的接待工作。明天将有m位客人从城市的不同的位置出发,到达他们各自的目的地。已知每个人的出发时间,出发地点和目的地。你的任务是用尽量少的出租车送他们,使得每次出租车接客人时,至少能提前一分钟到达他所在的位置。注意,为了满足这一条件,要么这位客人是这辆出租车接送的第一个人,要么在接送完上一个客人后,有足够的时间从上一个目的地开到这里。

为了简单起见,假定城区是网格型的,地址用坐标(x,y)表示,出租车从(x1,y1)到(x2,y2)处需要行驶|x1-x2|+|y1-y2|分钟。

分析

这个模型叫做DAG的最小路径覆盖。所谓最小路径覆盖,就是在图中找尽量少的路径,使得每个结点恰好在一条路径上(换句话说,不同的路径不能有公共点)。注意,单独的一个结点也可以作为一条路径。

DAG最小路径覆盖的解法如下:把所有的结点i拆为X结点i和Y结点i‘,如果图G中存在有向边i->j,则二分图中引入边i->j'。设二分图的最大匹配数为m,则结果就是n-m。因为匹配和路径覆盖是一一对应的。对于路径覆盖中的每条简单路径,除了最后一个“结尾结点”以外都有唯一的后继和他对应(既匹配结点),因此匹配数就是非结尾结点的个数,当匹配数达到最大时,此时,结尾结点的个数最少,既路径条数最少。

本题建模:每个客人是一个结点,如果同一个出租车接完客人u以后还来得及接客人v,连边u->v。不难发现,这个图是一个DAG,并且它的最小路径覆盖就是本题的答案。

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cmath> using namespace std;
const int maxn=+;
const int maxm=;
const int INF=;
struct Dinic{
int head[maxn],Next[maxm],to[maxm],cap[maxm],flow[maxm];
int sz,n,m,s,t;
bool vis[maxn];
int cur[maxn],d[maxn];
void init(int n){
this->n=n;
memset(head,-,sizeof(head));
this->sz=-;
}
void add_edge(int a,int b,int c){
++sz;
to[sz]=b;
cap[sz]=c;flow[sz]=;
Next[sz]=head[a];head[a]=sz;
++sz;
to[sz]=a;
cap[sz]=c;flow[sz]=c;
Next[sz]=head[b];head[b]=sz;
}
bool BFS(){
memset(vis,,sizeof(vis));
queue<int>Q;
vis[s]=;
d[s]=;
Q.push(s);
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=head[u];i!=-;i=Next[i]){
int v=to[i];
if(!vis[v]&&cap[i]>flow[i]){
vis[v]=;
d[v]=d[u]+;
Q.push(v);
}
}
}
return vis[t];
}
int DFS(int x,int a){
if(x==t||a==)return a;
int Flow=,f;
for(int& i=cur[x];i!=-;i=Next[i]){
int v=to[i];
if(d[v]==d[x]+&&(f=DFS(v,min(a,cap[i]-flow[i])))>){
Flow+=f;
flow[i]+=f;
flow[i^]-=f;
a-=f;
if(a==)break;
}
}
return Flow;
}
int Maxflow(int s,int t){
this->s=s,this->t=t;
int Flow=;
while(BFS()){
for(int i=;i<=n;i++)
cur[i]=head[i]; Flow+=DFS(s,INF);
}
return Flow;
}
}dinic;
int T,m;
int sth[maxn],stm[maxn],sx[maxn],sy[maxn],enx[maxn],eny[maxn];
int dist(int x1,int y1,int x2,int y2){
return abs(x1-x2)+abs(y1-y2);
}
void pass_time(int hou,int mi,int &Hou,int &Mi,int tim){
Mi=mi+tim;
Hou=hou+Mi/;
Mi=Mi%;
return;
}
int main(){
scanf("%d",&T);
for(int t=;t<=T;t++){
scanf("%d",&m);
dinic.init(*m+);
for(int i=;i<=m;i++){
scanf("%d:%d%d%d%d%d",&sth[i],&stm[i],&sx[i],&sy[i],&enx[i],&eny[i]);
} for(int i=;i<=m;i++){
for(int j=;j<=m;j++){
int tim=dist(sx[i],sy[i],enx[i],eny[i])+dist(enx[i],eny[i],sx[j],sy[j]);
int Enh,Enm;
pass_time(sth[i],stm[i],Enh,Enm,tim);
if(Enh*+Enm>=sth[j]*+stm[j])continue;
dinic.add_edge(i,j+m,);
}
}
for(int i=;i<=m;i++)
dinic.add_edge(,i,);
for(int i=;i<=m;i++)
dinic.add_edge(i+m,*m+,);
int ans=dinic.Maxflow(,*m+);
printf("%d\n",m-ans); }
return ;
}

【LA3126 训练指南】出租车 【DAG最小路径覆盖】的更多相关文章

  1. 训练指南 UVALive - 3126(DAG最小路径覆盖)

    layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mat ...

  2. uva1201 DAG 最小路径覆盖,转化为 二分图

    大白例题P356 你在一座城市里负责一个大型活动的接待工作.你需要去送m个人从出发地到目的地,已知每个人的出发时间出发地点,和目的地点,你的任务是用尽量少的出租车送他们,使得每次出租车接客人,至少能提 ...

  3. 1350 Taxi Cab Scheme DAG最小路径覆盖

    对于什么是DAG最小路径覆盖以及解题方法在我的另外的博客已经有了.http://www.cnblogs.com/Potato-lover/p/3980470.html 此题的题意: 公交车(出租车)车 ...

  4. POJ1422 Air Raid 【DAG最小路径覆盖】

    Air Raid Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6763   Accepted: 4034 Descript ...

  5. hdu3861 The King’s Problem 强连通缩点+DAG最小路径覆盖

    对多校赛的题目,我深感无力.题目看不懂,英语是能懂的,题目具体的要求以及需要怎么做没有头绪.样例怎么来的都不明白.好吧,看题解吧. http://www.cnblogs.com/kane0526/ar ...

  6. HDU 3861 The King’s Problem (强连通缩点+DAG最小路径覆盖)

    <题目链接> 题目大意: 一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.所有点只能属于一块区域:2,如果两点相互可达,则这两点必然要属于同一区域:3,区域内任意两点 ...

  7. bzoj 2044 三维导弹拦截——DAG最小路径覆盖(二分图)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2044 还以为是CDQ.发现自己不会三维以上的…… 第一问可以n^2.然后是求最长不下降子序列 ...

  8. POJ 1422 DAG最小路径覆盖

    求无向图中能覆盖每个点的最小覆盖数 单独的点也算一条路径 这个还是可以扯到最大匹配数来,原因跟上面的最大独立集一样,如果某个二分图(注意不是DAG上的)的边是最大匹配边,那说明只要取两个端点只要一条边 ...

  9. Taxi Cab Scheme UVALive - 3126 最小路径覆盖解法(必须是DAG,有向无环图) = 结点数-最大匹配

    /** 题目:Taxi Cab Scheme UVALive - 3126 最小路径覆盖解法(必须是DAG,有向无环图) = 结点数-最大匹配 链接:https://vjudge.net/proble ...

随机推荐

  1. jQuery 性能优化技巧

    原文地址:jQuery 性能优化技巧 博客地址:http://www.extlight.com 一.使用最新版本 jQuery 类库 二.合理使用选择器 # 推荐使用 $("#id" ...

  2. vue的动画组件(transition)

    当插入或删除包含在 transition 组件中的元素时,Vue 将会做以下处理: 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名. v-enter: 定 ...

  3. oracle版本及字符集查询

    查询oracle版本:select * from v$version; 查询oracle字符集:select * from nls_database_parameters;

  4. VS2017更新后无法使用stdlib.h

    这几天用VS写代码,每次打开工程就卡死,在网上找不到解决方法,于是想更新下vs碰碰运气. 更新后,打开速度恢复往日那般,但是代码中,提示我找不到 stdlib.h. 于是在电脑中,搜寻stdlib.h ...

  5. java代码---indexOf()方法

    总结:indexOf(String str,int index)方法.从参数指定位置开始,如果index值超过了字符串长度,则返回-1 package com.a.b; import java.io. ...

  6. 使用exe4j把java程序生成可执行的.exe文件

    exe4j可以很容易把一个jar打成exe.  下载地址:http://dl.dbank.com/c0owlopqf8 1.下载的安装文件,里面包含一个注册码生成的工具 2.安装exe4j以及破解(注 ...

  7. Joker的自动化之路

    系统篇     颜色 黄绿+金色 使用mac系统常用工具(包含svn,vim,crt,redis,php5,网络性能命令) 计算机硬件         linux发展史            cent ...

  8. django随机验证码

    Python生成随机验证码,需要使用PIL模块. 安装: 1 python3.5 -m pip install pillow 基本使用 1. 创建图片 1 2 3 4 5 6 7 8 9 from P ...

  9. python做语音信号处理

    音频信号的读写.播放及录音 标准的python已经支持WAV格式的书写,而实时的声音输入输出需要安装pyAudio(http://people.csail.mit.edu/hubert/pyaudio ...

  10. MySql——触发器

    触发器 什么叫触发器: 就是mysql中的一种“一触即发”的机器(机制). 其实只是预先定义好的一段代码.该段代码无需人工调用,而是会在‘预计’好的某个情形下自动执行. 通常就这几个情形: 对某个数据 ...