UVA 1201 - Taxi Cab Scheme(二分图匹配+最小路径覆盖)

UVA 1201 - Taxi Cab Scheme

题目链接

题意:给定一些乘客,每个乘客需要一个出租车,有一个起始时刻,起点,终点,行走路程为曼哈顿距离,每辆出租车必须在乘客一分钟之前到达,问最少需要几辆出租车

思路:如果一辆车载完一个乘客a,能去载乘客b,就连一条有向边,这样做完整个图形成一个DAG,然后要求的最少数量就是最小路径覆盖,利用二分图最大匹配去做,把每个点拆成两点,如果有边就连边,做一次最大匹配,n - 最大匹配数就是答案

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
#include <vector>
using namespace std;

const int N = 505;

int t, n;

struct People {
	int s, x1, y1, x2, y2;
	void read() {
		int h, m;
		scanf("%d:%d%d%d%d%d", &h, &m, &x1, &y1, &x2, &y2);
		s = h * 60 + m;
	}
	bool operator < (const People& c) const {
		return s < c.s;
	}
} p[N];

vector<int> g[N];

bool judge(People a, People b) {
	int tmp = a.s + abs(a.x2 - a.x1) + abs(a.y2 - a.y1) + abs(a.x2 - b.x1) + abs(a.y2 - b.y1);
	if (tmp < b.s) return true;
	return false;
}

int match[N], vis[N];

bool dfs(int u) {
	for (int i = 0; i < g[u].size(); i++) {
		int v = g[u][i];
		if (vis[v]) continue;
		vis[v] = 1;
		if (match[v] == -1 || dfs(match[v])) {
			match[v] = u;
			return true;
		}
	}
	return false;
}

int hungary() {
	int ans = 0;
	memset(match, -1, sizeof(match));
	for (int i = 0; i < n; i++) {
		memset(vis, 0, sizeof(vis));
		if (dfs(i)) ans++;
	}
	return ans;
}

int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &n);
		for (int i = 0; i < n; i++) {
			g[i].clear();
			p[i].read();
		}
		sort(p, p + n);
		for (int i = 0; i < n; i++)
			for (int j = i + 1; j < n; j++) {
				if (judge(p[i], p[j]))
					g[i].push_back(j);
			}
		printf("%d\n", n - hungary());
	}
	return 0;
}
时间: 2024-12-31 23:04:00

UVA 1201 - Taxi Cab Scheme(二分图匹配+最小路径覆盖)的相关文章

POJ 1422 Air Raid(二分图匹配最小路径覆盖)

POJ 1422 Air Raid 题目链接 题意:给定一个有向图,在这个图上的某些点上放伞兵,可以使伞兵可以走到图上所有的点.且每个点只被一个伞兵走一次.问至少放多少伞兵 思路:二分图的最小路径覆盖,每个点拆成两个点,然后根据有向边连边,然后答案为n - 最大匹配数 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace

POJ - 2060 Taxi Cab Scheme 二分图 最小路径覆盖

题目大意:有n项任务,给出每项任务的出发时间,出发地点和目的地. 当一个任务完成之后,如果 当前时间 + 到达另一个任务的出发地的时间 <= 另一个任务的出发时间 - 1 的话,那么就可以让这个人接下去完成这个任务了 问至少需要派多少人才可以完成任务 解题思路:这题和 poj-3216 Repairing Company很像 两个点集都是任务,如果一个任务完成了可以接下来完成另一个任务的话,那么这两个任务之间就存在关系了,这样二分图就建成了 因为要把所有的任务都完成,也就是说要覆盖所有点,这就变

poj 2060 Taxi Cab Scheme (二分匹配)

Taxi Cab Scheme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5710   Accepted: 2393 Description Running a taxi station is not all that simple. Apart from the obvious demand for a centralised coordination of the cabs in order to pick up

poj2060Taxi Cab Scheme(二分图匹配)

1 /* 2 题意: 出租车 有一个出发的时间,从点(a, b)到点(c, d),时间为 3 abs(a-c)+abs(b-d)! 一辆车可以在运完一个乘客后运另一个乘客, 4 条件是此车要在预约开始前一分钟之前到达出发地, 问最少需要几辆车 5 搞定所有预约. 6 7 思路:有向边进行建图,因为出发时间是升序的! 8 t0: (a0, b0) ->(c0, d0)表示预约在t0时间出发从(a,b)到(c,d);//节点x 9 t1: (a1, b1) ->(c1, d1)表示预约在t1时间出

POJ 3020 Antenna Placement ,二分图的最小路径覆盖

题目大意: 一个矩形中,有N个城市'*',现在这n个城市都要覆盖无线,若放置一个基站,那么它至多可以覆盖相邻的两个城市. 问至少放置多少个基站才能使得所有的城市都覆盖无线? 无向二分图的最小路径覆盖 = 顶点数 –  最大二分匹配数/2 路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联: #include<cstdio> #include<cstring> #include<vector> #include<algor

POJ 3020:Antenna Placement(无向二分图的最小路径覆盖)

Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6334   Accepted: 3125 Description The Global Aerial Research Centre has been allotted the task of building the fifth generation of mobile phone nets in Sweden. The most st

POJ 1422 二分图(最小路径覆盖)

Air Raid Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 7278   Accepted: 4318 Description Consider a town where all the streets are one-way and each street leads from one intersection to another. It is also known that starting from an i

二分图(最小路径覆盖)

求最小路径覆盖通常要拆点,将一个点拆分为两个 Description Consider a town where all the streets are one-way and each street leads from one intersection to another. It is also known that starting from an intersection and walking through town's streets you can never reach th

POJ-3020 Antenna Placement---二分图匹配&amp;最小路径覆盖&amp;建图

题目链接: https://vjudge.net/problem/POJ-3020 题目大意: 一个n*m的方阵 一个雷达可覆盖两个*,一个*可与四周的一个*被覆盖,一个*可被多个雷达覆盖问至少需要多少雷达能把所有的*覆盖 解题思路: 把每个*城市编号,然后每相邻两个城市之间连线.这里求最少多少个雷达可以覆盖完*,就是二分图匹配中的最小路径覆盖数,但是这里的图的边是双向的.举个例子 o*o **o ooo 这里可以编号成 010 230 000 那么有边<1,3><3,1><