poj2060Taxi Cab Scheme_最小覆盖路径问题

26 篇文章 0 订阅

题目链接

题意:

   租车公司有n个预约, 每个预约有时间和地点, 地点分布在二维整数坐标系上, 地点之间的行驶时间为两点间的曼哈顿距离
(|x1 - x2| + |y1 - y2|)。一辆车可以在运完一个乘客后运另一个乘客, 条件是此车要在预约开始前一分钟之前到达出发地, 问最少需要几辆车搞定所有预约。

给出一些预约的起始时间,出发地和目的地,问至少需要多少车可以满足所有的预约
对于任何一对预约,如果前一预约的结束时刻加上到达
下一个预约的所需时间小于下一个预约

的起始时间,就在两个预约之间连一条边,题目就转化为求该图的最小路径覆盖


看到这个题的第一眼,我觉得可以用贪心区间解决W,但是由于测试数据比较特殊(第二位乘客的起始地点正好的第一位乘客的下车目的地),我也忽略了司机的缓冲时间(到达下一个乘客预约地点的时间)。可是我还是不放弃贪心区间解决这个问题(我要继续想,先放上代码)

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int map[505][505];
int v2_link[505];
int v2_vis[505];
int sum,n;

struct node
{
	int s,a,b,c,d,e;

}q[505];

bool dfs(int x)
{
	int y;
	for(y=0;y<n;y++)
	{
		if(!v2_vis[y]&&map[x][y])
		{
			v2_vis[y]=1;
			
			if(v2_link[y]==-1||dfs(v2_link[y]))
			   {
			   	 v2_link[y]=x;
			   	 return true;
			   }
		}
	}
	return false;
}
int hungary()
{
	int i,sum=0;
	memset(v2_link,-1,sizeof(v2_link));
	
	for(i=0;i<n;i++)
	{
		memset(v2_vis,0,sizeof(v2_vis));
		if(dfs(i))
		  sum++;
	}
	return sum;
}
bool add(int x,int y)
{
	if(x==y)return 0;
	
	int temp=q[x].e+abs(q[y].a-q[x].c)+abs(q[y].b-q[x].d);

	if(temp<q[y].s)
	      return 1;
	return 0;
}
int main()
{
	int T,h,m,a,b,c,d,i,j;
	scanf("%d",&T);
	while(T--)
	{	 	 
     scanf("%d",&n);
     for(i=0;i<n;i++)
     {
     	scanf("%d:%d",&h,&m);
        q[i].s=h*60+m;
        
        scanf("%d%d%d%d",&q[i].a,&q[i].b,&q[i].c,&q[i].d);
        q[i].e=q[i].s+abs(q[i].c-q[i].a)+abs(q[i].d-q[i].b);
        
     }
     memset(map,0,sizeof(map));
     
     for(i=0;i<n;i++)
       for(j=0;j<n;j++)
	      map[i][j]=add(i,j); 

       printf("%d\n",n-hungary());
    }
	return 0;
}

贪心区间(错误


#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;


struct  node
{
	int s,e;
}q[505];
int cmp(node a,node b)
{
	return a.s<b.s;
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int n,i,a,b,c,d,e,f;
		scanf("%d",&n);
		for(i=0;i<n;i++)
		{
			scanf("%d:%d%d%d%d%d",&a,&b,&c,&d,&e,&f);
			q[i].s=a*60+b;
			q[i].e=q[i].s+abs(e-c)+abs(f-d);
		}
		sort(q,q+n,cmp);
		int max=q[0].e;
		int sum=n;
		for(i=1;i<n;i++)
		{
			if(q[i].s>max)
			{
				sum--;
				max=q[i].e;
			}
			else
			{
				
				if(q[i].e<max)
				{
					max=q[i].e;
				}
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值