1. 程式人生 > >UVALive 3126 Taxi Cab Scheme(最大匹配問題)

UVALive 3126 Taxi Cab Scheme(最大匹配問題)

Running a taxi station is not all that simple. Apart from the obvious demand for a centralised coordi-
nation of the cabs in order to pick up the customers calling to get a cab as soon as possible, there is
also a need to schedule all the taxi rides which have been booked in advance. Given a list of all booked
taxi rides for the next day, you want to minimise the number of cabs needed to carry out all of the
rides.
For the sake of simplicity, we model a city as a rectangular grid. An address in the city is denoted
by two integers: the street and avenue number. The time needed to get from the address a, b to c, d by
taxi is |a − c| + |b − d| minutes. A cab may carry out a booked ride if it is its first ride of the day, or
if it can get to the source address of the new ride from its latest, at least one minute before the new
ride‘s scheduled departure. Note that some rides may end after midnight.
Input


On the first line of the input is a single positive integer N, telling the number of test scenarios to follow.
Each scenario begins with a line containing an integer M, 0 < M < 500, being the number of booked
taxi rides. The following M lines contain the rides. Each ride is described by a departure time on the
format hh : mm (ranging from 00:00 to 23:59), two integers a b that are the coordinates of the source
address and two integers c d that are the coordinates of the destination address. All coordinates are at
least 0 and strictly smaller than 200. The booked rides in each scenario are sorted in order of increasing
departure time.
Output

For each scenario, output one line containing the minimum number of cabs required to carry out all
the booked taxi rides.
Sample Input
2
2
08:00 10 11 9 16
08:07 9 16 10 11
2
08:00 10 11 9 16
08:06 9 16 10 11
Sample Output
1
2
參考題解

題意:有n個客人要來,給出n個客人的到達時間和出發地點以及目的地點,你的任務是用盡量少的計程車去接送客人,接送客人要求出租車至少要比客人先到達出發地點一分鐘,從(x1,y1)到(x2,y2)花費時間 |x2-x1|+|y2-y1| 分鐘,求最少需要的計程車數量。

我是看的題解的思路,如題解:我們先把每個人的資訊記錄下來,然後按時間排個序,然後呢,儲存一下他送完前一個乘客之後後面可以趕去的地點,那麼就可以看成一個二分圖了,這樣遍歷一下每一個點,那麼他如果能到下一個點,就會產生一組配對,最後用n減去配對數就可以了。可能這樣說有點不清楚,我們因為我們每一個人都會遍歷到,那麼他後面如果還能繼續接人,那麼就有一個配對,但是我們遍歷到第二個點的時候,我們這個點可能與前一個點形成了一個配對,所以我們減去配對數的時候,其實就是把一輛車跑完第一個地方之後又能去的地方都減去了,因為那些地方都不需要多餘的車了,所以就直接從總數裡面減掉了。
emmm,我直接把題解程式碼貼上了哈:

#include<cstdio>
#include<cstring>
#include<vector>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=500;
struct node
{
	int time,x1,y1,x2,y2,dist;
}a[maxn];
int vis[maxn],left[maxn],n;
vector<int>G[maxn];
void init()
{
	for(int i=0;i<maxn;i++)
	G[i].clear();
	memset(left,0,sizeof(left));
}
bool cmp(node c,node d)
{
	return c.time<d.time;
}
int dis(int i,int j)
{
	return abs(a[j].x1-a[i].x2)+abs(a[j].y1-a[i].y2);
}
int dfs(int i)
{
	for(int j=0;j<G[i].size();j++)
	{
		int v=G[i][j];
		if(!vis[v])
		{
			vis[v]=1;
			if(!left[v]||dfs(left[v]))
			{
				left[v]=i;
				return 1;
			}
		}
	}
	return 0;
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		init();
		for(int i=1;i<=n;i++)
		{
			int t1,t2;
			scanf("%d:%d%d%d%d%d",&t1,&t2,&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2);
			a[i].time=t1*60+t2;
			a[i].dist=abs(a[i].x1-a[i].x2)+abs(a[i].y1-a[i].y2);
		}
		sort(a+1,a+n+1,cmp);
		for(int i=1;i<n;i++)
		for(int j=i+1;j<=n;j++)
		{
			if(a[j].time-1>=a[i].time+a[i].dist+dis(i,j))
			G[i].push_back(j);
		}
		int ans=0;
		for(int i=1;i<=n;i++)
		{
			memset(vis,0,sizeof(vis));
			ans+=dfs(i);
		}
		printf("%d\n",n-ans);
	}
}