Problem E: E.疫情控制

Problem E: E.疫情控制

Time Limit: 3 Sec   Memory Limit: 128 MB
Submit: 6   Solved: 4
[ Submit][ Status][ Web Board]

Description


据某省水产部门通报,A市大面积范围水产养殖区爆发ADH氏菌疫情,导致大量鱼苗死亡,养殖户经济损失巨大。必须尽快控制疫情,使水产养殖秩序回归正常。

此次ADH氏菌疫情传染范围较大,涉及到 M 个地区。要想对某个地区I疫情进行控制,必须先控制住上游地区I-1的疫情,再对该地区监测,管理,施药才能彻底清除传染性,真正做到水体改良,水质改善。

不妨设M 个地区的编号1,2,…,M,首先,地区1的疫情得到控制后,才能在1天后控制地区2。类推,仅当地区i的疫情得到控制后,1天后才能去控制地区i+1;当第M个地区疫情被控制后,才算彻底控制住A市疫情。

如何做到早发现,早报告,早隔离,早治理,按照属地化管理原则,A市准备建立 N 个防疫中心。当一个防疫中心启用后,它可以对方圆半径 R 范围内的地区疫情加以控制,并且持续控制5天。N 个防疫中心也不是同时启动,当一个防疫中心启用5天后,才能启动另一个防疫中心。

启用一个防疫中心需要大量的人力,物力。请你设计一个方案,如何启用尽可能少的防疫中心就能够对A市所有疫情加以控制。


约束条件】  

  1≤K5   1 ≤M, N  100,1≤ R≤1000,    0≤所有坐标X,Y≤10000

  所有数据都是整数。 数据之间有一个空格。

Input

第一行: K      表示有多少组测试数据。

接下来对每组测试数据:

1:      M  N  R        

2~M+1行: X1i  Y1i       表示第 i 地区所在的坐标 i=1,…,M

M+2~M+N+1:     X2 j  Y2j    表示第 j 防疫中心的坐标 j=1,…,N

Output

对于每组测试数据,输出占一行:最少启用的防疫中心数量

Sample Input

1
4 3 6
0 6
6 6
6 0
0 0
0 3
1 1
1 5

Sample Output

2

HINT

启用3号防疫中心可以控制地区1,2


启用2号防疫中心可以控制地区3,4

解题思路:
         这个题可以看作是
         最少调用几个防疫中心可以控制所有的病情
         如果这个前提都看不出来 欢迎私聊


(1)考虑每个防疫中心能控制多少有疫情的城市 <Contrue()函数>
(2)假设动用第k个防疫中心,那么用递归的方法找出可以满足条件的所有的防疫中心。<FindMinDevice()函数>

        递归之前的防疫中心不再考虑     从k,k+1,....N


(3)MMK 用来记录所调用的最少的防疫中心是几个

代码如下:

#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
typedef struct
{
	int x;
	int y;
	int Con[101];//被控制的城市的 代号
	int length;  //记录存放的 防疫中心 可以控制城市的 个数
}Coord;              //用结构体存城市和防疫中心的坐标

int M, N, R, MMK= 101;
int Correct[100] = { 0 };       //地区改善情况的数组
Coord area[100], project[100];  //地区数组 防疫中心数组

void FindMinDevice(int k, int sum)
{
	for (int j = 0; j < project[k].length; j++)
		if (Correct[project[k].Con[j]] == 0)
			Correct[project[k].Con[j]] = k + 1; //此循环表示该城市已净化

	int flag = 0;

	for (int q = 0; q < M; q++)
	{
		if (Correct[q] == 0)
		{
			flag = 1;
			break;
		}
	}

	if (flag == 0 && sum <MMK)         //如果所有城市都改善成功,就退出递归
	{
		MMK= sum;
		return;
	}

	for (int i = k + 1; i < N; i++)
		FindMinDevice(i, sum + 1); //不用考虑该防疫中心之前的,防止重复

	for (int p = 0; p < M;p++)
		if (Correct[p] == k+1)
			Correct[p] = 0;    //回溯城市的疫情,不影响其他递归的调用
}

void contrue(int j)
{
	for (int i = 0; i < M; i++)
	{
		if (sqrt(pow((area[i].x - project[j].x), 2) + pow((area[i].y - project[j].y), 2)) <= R)
		{
			project[j].Con[project[j].length] = i;       //找出能被该防疫中心控制的城市
			project[j].length++;
		}
	}
}
int main()
{
	int K;
	cin >> K;
	while (K--)
	{
		MMK= 101;

		cin >> M >> N >> R;
		for (int i = 0; i < M; i++)
			cin >> area[i].x >> area[i].y;

		for (int j = 0; j < N; j++)
		{
			cin >> project[j].x >> project[j].y;
			project[j].length = 0;
			contrue(j);
		}

		for (int k = 0; k < N; k++)
			FindMinDevice(k, 1);

		cout << MMK<< endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/tobealistenner/article/details/80384412