UVALive 3126 出租车(DAG的最小不相交路径覆盖)
2016-10-12 23:04
423 查看
题目:https://vjudge.net/contest/136139#problem/G
题意:
现在有n个客户,他们要乘出租车,他们每个人,有一个出发时间t,起点位置和终点位置。现在要安排尽量少的出租车送他们到目的地。出租车必须在客户出发前至少提前一分钟赶到那个客户出发的位置才行,或者这个客户就是这辆出租车的第一个乘客。让你输出需要的最少的出租车数。
分析:
模型是DAG的最小不相交路径覆盖(在图中找尽量少的路径,使得每个节点恰好在一条路径上,也就是说不同路径不能有公共点)
解法书上已经写得十分详细了,简单写一下
拆点:把结点i拆成X结点i和Y结点i’
对于有向边i->j,在二分图中加边i->j’
那么答案就是n-m(n是节点数,m是最大匹配数)
Why?
因为匹配和路径覆盖是一 一对应的,匹配数就是非结尾结点的个数,因为对于每条简单路径,除了最后一个结尾结点之外都有唯一的后继和匹配结点对应。
结尾结点最少,即路径条数最少
(可能不太好想,可以结合二分图的最大独立集去理解,二者有异曲同工之处,就像上一题一样,也可以从最小路径覆盖的角度去理解)
代码:
题意:
现在有n个客户,他们要乘出租车,他们每个人,有一个出发时间t,起点位置和终点位置。现在要安排尽量少的出租车送他们到目的地。出租车必须在客户出发前至少提前一分钟赶到那个客户出发的位置才行,或者这个客户就是这辆出租车的第一个乘客。让你输出需要的最少的出租车数。
分析:
模型是DAG的最小不相交路径覆盖(在图中找尽量少的路径,使得每个节点恰好在一条路径上,也就是说不同路径不能有公共点)
解法书上已经写得十分详细了,简单写一下
拆点:把结点i拆成X结点i和Y结点i’
对于有向边i->j,在二分图中加边i->j’
那么答案就是n-m(n是节点数,m是最大匹配数)
Why?
因为匹配和路径覆盖是一 一对应的,匹配数就是非结尾结点的个数,因为对于每条简单路径,除了最后一个结尾结点之外都有唯一的后继和匹配结点对应。
结尾结点最少,即路径条数最少
(可能不太好想,可以结合二分图的最大独立集去理解,二者有异曲同工之处,就像上一题一样,也可以从最小路径覆盖的角度去理解)
代码:
// LA3126 Taxi Cab Scheme // Rujia Liu #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int maxn = 500 + 5; // 单侧顶点的最大数目 // 二分图最大基数匹配,邻接矩阵写法 struct BPM { int n, m; // 左右顶点个数 int G[maxn][maxn]; // 邻接表 int left[maxn]; // left[i]为右边第i个点的匹配点编号,-1表示不存在 bool T[maxn]; // T[i]为右边第i个点是否已标记 void init(int n, int m) { this->n = n; this->m = m; memset(G, 0, sizeof(G)); } bool match(int u) { for(int v = 0; v < m; v++) if(G[u][v] && !T[v]) { T[v] = true; if (left[v] == -1 || match(left[v])) { left[v] = u; return true; } } return false; } // 求最大匹配 int solve() { memset(left, -1, sizeof(left)); int ans = 0; for(int u = 0; u < n; u++) { // 从左边结点u开始增广 memset(T, 0, sizeof(T)); if(match(u)) ans++; } return ans; } }; BPM solver; int x1[maxn], y1[maxn], x2[maxn], y2[maxn], t1[maxn], t2[maxn]; inline int dist(int a, int b, int c, int d) { return abs(a-c) + abs(b-d); } int main() { int T; scanf("%d", &T); while(T--) { int n; scanf("%d", &n); for(int i = 0; i < n; i++) { int h, m; scanf("%d:%d%d%d%d%d", &h, &m, &x1[i], &y1[i], &x2[i], &y2[i]); t1[i] = h*60+m; t2[i] = t1[i] + dist(x1[i], y1[i], x2[i], y2[i]); } solver.init(n, n); for(int i = 0; i < n; i++) for(int j = i+1; j < n; j++) if(t2[i] + dist(x2[i], y2[i], x1[j], y1[j]) < t1[j]) solver.G[i][j] = 1; // 至少要提前1分钟到达 printf("%d\n", n - solver.solve()); } return 0; }
相关文章推荐
- UVALive-3126 Taxi Cab Scheme (DAG的最小路径覆盖)
- UVAlive3126 Taxi Cab Scheme(DAG的最小路径覆盖)
- UVAlive3126 Taxi Cab Scheme(DAG的最小路径覆盖)
- Taxi Cab Scheme UVALive - 3126 最小路径覆盖解法(必须是DAG,有向无环图) = 结点数-最大匹配
- UVALive 3126 Taxi Cab Scheme(DAG的最小路径覆盖)
- UVaLive 3126 Taxi Cab Scheme (最小路径覆盖)
- UVAlive 3126(最小路径覆盖)
- uvalive3126最小路径覆盖
- uva 3126 出租车 (最小路径覆盖)
- Delivering Goods UVALive - 7986(最短路+最小路径覆盖)
- uva1201 DAG 最小路径覆盖,转化为 二分图
- UVAlive 6571 最小路径覆盖变形(带权) 拆点+ISAP
- UVALive 4654 (最小路径覆盖)
- POJ2594 Treasure Exploration[DAG的最小可相交路径覆盖]
- POJ 2594 浅谈可相交的二分图DAG最小路径覆盖
- POJ Treasure Exploration(DAG最小可相交路径覆盖)
- LA 3126 - Taxi Cab Scheme【DAG最小路径覆盖】
- UVA-1201 - Taxi Cab Scheme(POJ-2060)--DAG的最小路径覆盖
- UVAlive 7368 Airports(建图+最小路径覆盖)
- POJ 1422 Air Raid(DAG最小路径覆盖)