二分搜索+匈牙利算法:ZOJ3156 Taxi

死磕了近四个小时……智商是真的捉急

Time Limit: 1 Second      Memory Limit: 32768 KB

As we all know, it often rains suddenly in Hangzhou during summer time.I suffered a heavy rain when I was walking on the street yesterday, so I decided to take a taxi back school. I found that there were n people on the street trying to take taxis, and m taxicabs on the street then. Supposing that the cars waited still and each person walked at a speed of v, now given the positions of the n persons and the m taxicabs, you should find the minimum time needed for all the persons to get on the taxicabs. Assume that no two people got on the same taxicab.

Input

For each case, you are given two integers 0 <= n <= 100 and n <= m <= 100 on the first line, then n lines, each has two integers 0 <= XiYi <= 1000000 describing the position of the ith person, then m lines, each has two integers 0 <= xiyi <= 1000000 describing the position the ith taxicab, then a line has a float 0.00001 < v <= 10000000 which is the speed of the people.

Output

You shuold figue out one float rounded to two decimal digits for each case.

Sample Input

2 3
0 0
0 1
1 0
1 1
2 1
1

Sample Output

1.00

    算出每个人到每个出租车直线距离的最短时间,对所有时间排序后,二分搜索可以满足所有人都到达一辆出租车的最短时间,判断是否可以到达用匈牙利算法。

#include<iostream>
#include<iomanip>
#include<cmath>
#include<cstring>
#define amax 105
#define func(i,j) (sqrt(pow((double)(X1[i]-X2[j]),2)+pow((double)(Y1[i]-Y2[j]),2))/speed)
void quicksort(double* aim, int left, int right);
void swap(double* a, double* b);
double mbsearch(int people, int car, int cnt);
int xylstart(int people, int car, double max);
bool xylfind(int now, int car, double max);
int X1[amax], Y1[amax];
int X2[amax], Y2[amax];
double matrix[amax][amax];
double arrays[amax*amax];
int main(int argc, char* argv[])
{
	int n, m;
	while (std::cin >> n >> m)
	{
		for (int i = 1; i <= n; i++)
			std::cin >> X1[i] >> Y1[i];
		for (int i = 1; i <= m; i++)
			std::cin >> X2[i] >> Y2[i];
		double speed;
		std::cin >> speed;
		int cnt = 1;
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
				arrays[cnt++] = matrix[i][j] = func(i, j);
		quicksort(arrays,1,cnt-1);
		std::cout.setf(std::ios::fixed);
		std::cout << std::setprecision(2)<<mbsearch(n, m, cnt - 1) << std::endl;
	}
	return 0;
}
void quicksort(double* aim, int left, int right)
{
	if (left > right)
		return;
	double temp = aim[left];
	int i = left;
	int j = right;
	while (i < j)
	{
		while (aim[j] >= temp && i < j)
			j--;
		while (aim[i] <= temp && i < j)
			i++;
		if (i < j)
			swap(&aim[i], &aim[j]);
	}
	aim[left] = aim[i];
	aim[i] = temp;
	quicksort(aim, i + 1, right);
	quicksort(aim, left, i - 1);
	return;
}
void swap(double* a, double* b)
{
	double temp = *a;
	*a = *b;
	*b = temp;
}
bool book[amax];
int getcar[amax];
double mbsearch(int people, int car, int cnt)
{
	int l = 1;
	int r = cnt;
	double x = 0.0;
	while (l <= r)
	{
		int ind = (l + r) / 2;
		if (xylstart(people, car, arrays[ind]))
		{
			x = arrays[ind];
			r = ind - 1;
		}
		else
			l = ind + 1;
	}
	return x;
}
int xylstart(int people, int car, double max)
{
	memset(getcar, 0, sizeof(getcar));
	for (int i = 1; i <= people; i++)
	{
		memset(book, 0, sizeof(book));
		if (!xylfind(i, car, max))
			return false;
	}
	return true;
}
bool xylfind(int now, int car, double max)
{
	for (int i = 1; i <= car; i++)
	{
		if (matrix[now][i] <= max && book[i] == false)
		{
			book[i] = true;
			if (!getcar[i] || xylfind(getcar[i], car, max))
			{
				getcar[i] = now;
				return true;
			}
		}
	}
	return false;
}

    *mbsearch函数里的 x 变量必须初始化为 0 ,不能是随机值!这是个深坑…因为 n 可以是 0 ,所以n是 0 的时候会跳过二分搜索,直接输出 x ,此时 x 应该是 0 。

    直接用algorithm的sort排序会更快更方便。

END

猜你喜欢

转载自blog.csdn.net/belous_zxy/article/details/80719947