LA 3126 出租车

题目链接:https://vjudge.net/problem/UVALive-3126

题意:有m个客人,位于不同的位置,去一些地方,出发的时间给出,要一些出租车去接,但是,每辆出租车要在出发前一分钟要到,问:最少要几辆出租车;

分析:最少路径覆盖(在图中找尽量少的路径,使得每个节点恰好在一条路径上)

建图: 一个点拆成 i i‘,i->j 就连一条边到 j‘;

答案是 n - 最大匹配;

证明:之前有证明过,很有意思;

这里,就是从一个接完客人到另下一个客人,是否可以接到,能就连一条边;

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 const int maxn = 500 + 5; // 单侧顶点的最大数目
 8
 9 struct BPM {
10     int n,m;
11     vector<int> G[maxn];
12     int left[maxn];
13     bool T[maxn];
14
15     int right[maxn];
16     bool S[maxn];
17
18     void init(int n,int m) {
19         this->n = n;
20         this->m = m;
21         for(int i=0; i<n; i++)
22             G[i].clear();
23     }
24
25     void AddEdge(int u,int v) {
26         G[u].push_back(v);
27     }
28
29     bool match(int u) {
30         S[u] = true;
31         for(int i=0; i<G[u].size(); i++) {
32             int v = G[u][i];
33             if(!T[v]) {
34                 T[v] = true;
35                 if(left[v]==-1||match(left[v])) {
36                     left[v] = u;
37                     right[u] = v;
38                     return true;
39                 }
40             }
41         }
42         return false;
43     }
44
45     int solve() {
46         memset(left,-1,sizeof(left));
47         memset(right,-1,sizeof(right));
48         int ans = 0;
49         for(int u=0; u<n; u++) {
50             memset(S,0,sizeof(S));
51             memset(T,0,sizeof(T));
52             if(match(u))
53                 ans++;
54         }
55         return ans;
56     }
57
58 } sol;
59
60
61 int x1[maxn], y1[maxn], x2[maxn], y2[maxn], t1[maxn], t2[maxn];
62
63 int dist(int a, int b, int c, int d) {
64     return abs(a-c) + abs(b-d);
65 }
66
67 int main() {
68     int T;
69     scanf("%d", &T);
70     while(T--) {
71         int n;
72         scanf("%d", &n);
73         for(int i = 0; i < n; i++) {
74             int h, m;
75             scanf("%d:%d%d%d%d%d", &h, &m, &x1[i], &y1[i], &x2[i], &y2[i]);
76             t1[i] = h*60+m;
77             t2[i] = t1[i] + dist(x1[i], y1[i], x2[i], y2[i]);
78         }
79         sol.init(n, n);
80         for(int i = 0; i < n; i++)
81             for(int j = i+1; j < n; j++)
82                 if(t2[i] + dist(x2[i], y2[i], x1[j], y1[j]) < t1[j])
83                     sol.AddEdge(i,j);
84         printf("%d\n", n - sol.solve());
85     }
86     return 0;
87 }

时间: 2024-10-10 06:02:50

LA 3126 出租车的相关文章

LA 3126 二分匹配---DAG中的最小路径应用

题意:有 n 个顾客 , 需要坐出租车从一个地方去另一个地方 , 每个顾客的出发时间.出发地点.目的地点都已给出 , 从出发地点到目的地点的时间为两地之间的路径长度 , 并且出租车要比顾客的出发时间早一分钟到达 , 问最少需要派出多少辆出租车. 解法:我们先这样来构图 , 每个顾客是一个结点,如果同一个出租车在接完客人 u 之后还来得及节客人 v , 那么就在 u 到 v 之间连一条有向边 . 由此可以发现 , 这个图是一个DAG , 那么我们就只需要找最小路径覆盖(最小路径覆盖:是指在图中找尽

二分图最大匹配,最小路径覆盖,最小点覆盖,最大独立集,最小边覆盖与建图方法

转载请注明出处(别管写的好坏,码字也不容易):http://blog.csdn.net/hitwhacmer1 前言:         有自己写的,有摘的别人的,前面是摘的,也是无心整理,出错是难免的,反正我都不会证明,智人见智,别被我误导了. §1图论点.边集和二分图的相关概念和性质 点覆盖.最小点覆盖 点覆盖集即一个点集,使得所有边至少有一个端点在集合里.或者说是"点" 覆盖了所有"边"..极小点覆盖(minimal vertex covering):本身为点覆

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

layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mathjax: true tags: - 二分图 - 图论 - 训练指南 - 最小路径覆盖 Taxi Cab Scheme UVALive - 3126 题目大意:n个客人,从城市的不同位置出发,到达他们的目的地.已知每个人的出发时间hh:mm,出发地点(x1,y1)及目的地(x2,y2),要求使用最少的出租车接

luogu 3126 回文的路径

https://www.luogu.org/problem/show?pid=3126 考虑dp,从两头走到中间. f[i][j][k][l]表示从左上角走到(i,j),从右下角走到(k,l),路径长度相等,所经过路径相同的方案数. 方程不再赘述. 考虑步数要相同,所以只要枚举步数和行就好. f[i][j][k]表示第一个点在第j行,第2个点在第k行,走i步的方案数. 所以得出方程f[i][j][k]=(f[i-1][j-1][k]+f[i-1][j][k+1]+f[i-1][j-1][k+1]

hdu 5745 la vie en rose

这道题的官方题解是dp,但是可以暴力出来.改天再研究怎么dp. 暴力的时候,如果计算sum的时候,调用strlen函数会超时,可见这个函数并不是十分的好.以后能不用尽量不用. La Vie en rose Time Limit: 14000/7000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 861    Accepted Submission(s): 461 Problem

让MAC OS也能使用LL LA L等LS的别名

linux下默认ll是ls -l的别名.OS X下默认不支持.习惯了linux下使用ll,我们同样也可以将习惯搬到os x下的shell中. 再当前用户家目录下新建.bash_profile文件.根据你的习惯,添加下面格式内容即可. 1 2 3 alias ll='ls -l' alias la='ls -a' alias l='ls -la' 然后执行:source .bash_profile你还可以添加你喜欢的其他别名.

LA 3942 Remember the Word (Trie)

Remember the Word 题目:链接 题意:给出一个有S个不同单词组成的字典和一个长字符串.把这个字符串分解成若干个单词的连接(单词可以重复使用),有多少种方法? 思路:令d[i]表示从字符i开始的字符串(后缀s[i..L])的分解数,这d[i] = sum{d(i+len(x)) | 单词x是其前缀}.然后将所有单词建成一个Trie树,就可以将搜索单词的复杂度降低. 代码: #include<map> #include<set> #include<queue>

LA 2678 Subsequence

有一个正整数序列,求最短的子序列使得其和大于等于S,并输出最短的长度. 用数组b[i]存放序列的前i项和,所以b[i]是递增的. 遍历终点j,然后在区间[0, j)里二分查找满足b[j]-b[i]≥S的最大的i,时间复杂度为O(nlongn). 这里二分查找用到库函数lower_bound() 1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #inclu

LA 4127 - The Sky is the Limit (离散化 扫描线 几何模板)

题目链接 非原创 原创地址:http://blog.csdn.net/jingqi814/article/details/26117241 题意:输入n座山的信息(山的横坐标,高度,山底宽度),计算他们的轮廓线, 即露出来的表面边长,有些山是重叠的不计.空白地带不计,每座山都是等腰三角形. 分析:大白书P414页. 求小山的总长度,用一些虚线将其离散化,分成一段一段的,特征点:山脚,山顶,交点.这样就能保 证相邻两个扫描点之间再无交点.然后一最上面的点就是分割点,维护上一个点lastp即可. 1