Taxi Cab Scheme
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 310 Accepted Submission(s): 195
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.
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
1 2
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1960
题意:样例1中: 8:00的时候要把第一位乘客从(10,11)送到(9,16),花费时间为6min(即曼哈顿距离)。
这辆车可以在(9,16)等到08:07 的时候送第二名乘客到达目的地。
而样例2中,第二名乘客08:06就要出发,而第一辆车08:06才到,所以要重新派一辆车。因为题目中说"The booked rides in each scenario are sorted in order of increasing departure time."
这道题很难想到是二分匹配的最小路径覆盖。
想到的话建图也是关键。
再写一遍公式:
最小路径覆盖=顶点数 - 最大匹配数。
具体细节看代码吧。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
int n;
const int maxn=500+5;
bool a[maxn][maxn];
bool vis[maxn];
int link[maxn];
struct Node
{
int sx,sy;//起点
int ex,ey;//终点
int s,e;//到达时间,离开时间
}node[maxn];
bool Find(int x)
{
for(int i=0;i<n;i++)
{
if(!vis[i]&&a[x][i])
{
vis[i]=true;
if(!link[i]||Find(link[i]))
{
link[i]=x;
return true;
}
}
}
return false;
}
int Hungery()
{
int ans=0;
memset(link,0,sizeof(link));
for(int i=0;i<n;i++)
{
memset(vis,false,sizeof(vis));
if(Find(i))
ans++;
}
return ans;
}
int main()
{
int T;
//freopen("data/1350.txt","r",stdin);
//freopen("data/1350_me.txt","w",stdout);
cin>>T;
while(T--)
{
cin>>n;
int h,m,sx,sy,ex,ey;
for(int i=0;i<n;i++)
{
scanf("%d:%d",&h,&m);
node[i].s=h*60+m;
cin>>sx>>sy>>ex>>ey;
node[i].sx=sx,node[i].sy=sy;
node[i].ex=ex,node[i].ey=ey;
node[i].e=node[i].s+abs(sx-ex)+abs(sy-ey);
}
memset(a,false,sizeof(a));
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
int t=abs(node[i].ex-node[j].sx)+abs(node[i].ey-node[j].sy);
//第i个点的结束时间+到达第j个点的时间<第j个点的开始时间
if(i!=j&&node[i].e+t<node[j].s)
{
a[i][j]=true;
}
}
}
cout<<n-Hungery()<<endl;
}
return 0;
}
尊重原创,转载请注明出处:http://blog.csdn.net/hurmishine