HDU 1350(Taxi Cab Scheme)

HDU 专栏收录该内容
351 篇文章 0 订阅

将每个客人作为一个结点,如果一个客人从起点到终点的时间+从终点到下一个客人起点的时间+1<=两位客人的时间差,则说明用一辆车可以运送两人,在两人之间连线,形成二分图。

然后计算二分图的最小路径覆盖数,使用匈牙利算法计算最大匹配数,最小路径覆盖数 = 结点数 - 最大匹配数。

#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXM = 505;

int M; //乘客数量
int sx[MAXM], sy[MAXM], ex[MAXM], ey[MAXM]; //起点坐标,终点坐标
int time[MAXM]; //从起点到终点的用时(分钟)
int mp[MAXM][MAXM]; //二分图
int vis[MAXM], match[MAXM]; //结点访问情况,结点匹配情况

//(x1,y1)至(x2,y2)的曼哈顿距离
int dis(int x1, int y1, int x2, int y2)
{
	return abs(x1 - x2) + abs(y1 - y2);
}

//查找从结点x出发的增广路径
bool find(int x)
{
	for (int i = 0; i < M; i++)
	{
		if (mp[x][i] && !vis[i]) //x和i之间有连线且i未被访问
		{
			vis[i] = true;
			//i未匹配或者从i的匹配点出发能找到增广路径
			if (match[i] == -1 || find(match[i]))
			{
				match[i] = x;
				return true;
			}
		}
	}
	return false;
}

int main()
{
	int N;
	
	scanf("%d", &N);
	while (N--)
	{
		scanf("%d", &M);
		int hour, second; //时,分
		for (int i = 0; i < M; i++)
		{
			scanf("%d:%d %d%d%d%d", &hour, &second, &sx[i], &sy[i], &ex[i], &ey[i]);
			time[i] = hour * 60 + second;
		}

		memset(mp, 0, sizeof(mp));
		for (int i = 0; i < M; i++) //形成二分图
		{
			for (int j = i + 1; j < M; j++)
				if (time[i] + dis(sx[i], sy[i], ex[i], ey[i]) + dis(ex[i], ey[i], sx[j], sy[j]) + 1 <= time[j])
					mp[i][j] = 1;
		}

		memset(match, -1, sizeof(match));
		int total = 0; //二分图的最大匹配数
		for (int i = 0; i < M; i++)
		{
			memset(vis, 0, sizeof(vis));
			if (find(i))
				++total;
		}
		printf("%d\n", M - total);
	}
	return 0;
}

继续加油。

  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值