解题思路:
把每一个可发射导弹的时间看成一个发射装置,总共n * m个,然后二分答案
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <string.h>
#include <vector>
#include <queue>
#include <math.h>
#include <set>
#include <map>
#include <stack>
#define LL long long
#define FOR(i, x, y) for(int i=x;i<=y;i++)
using namespace std;
const double eps = 1e-8;
const int MAXN = 2500 + 10;
int vis[MAXN];
vector<int>G[60];
int match[MAXN];
double t[MAXN][60];
struct Point
{
int x, y;
}A[MAXN], B[MAXN];
int n, m;
double t1, t2, v;
double dis(Point A, Point B)
{
double x = A.x - B.x;
double y = A.y - B.y;
return sqrt(x * x + y * y);
}
int path(int u)
{
int sz = G[u].size();
for(int i=0;i<sz;i++)
{
int v = G[u][i];
if(!vis[v])
{
vis[v] = 1;
if(match[v] == -1 || path(match[v]))
{
match[v] = u;
return 1;
}
}
}
return 0;
}
int MaxMatch()
{
int res = 0;
memset(match, -1, sizeof(match));
for(int i=0;i<m;i++)
{
memset(vis, 0, sizeof(vis));
res += path(i);
}
return res;
}
double d[MAXN][60];
int main()
{
while(scanf("%d%d%lf%lf%lf", &n, &m, &t1, &t2, &v)!=EOF)
{
t1 /= 60;
FOR(i, 0, m-1) scanf("%d%d", &B[i].x, &B[i].y);
FOR(i, 0, n-1) scanf("%d%d", &A[i].x, &A[i].y);
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
d[i][j] = dis(A[i], B[j]);
}
FOR(k, 0, m-1)
{
FOR(i, 0, n-1)
{
FOR(j, 0, m-1)
{
t[i*m+k][j] = k * t2 +(k+1) * t1 + d[i][j] / v;
}
}
}
double l = 0, r = 2000000000000.0;
while(r - l >= eps)
{
double mid = (l + r) * 0.5;
for(int i=0;i<60;i++) G[i].clear();
for(int i=0;i<n*m;i++)
{
for(int j=0;j<m;j++)
{
if(t[i][j] <= mid) G[j].push_back(i);
}
}
if(MaxMatch() == m)
{
r = mid;
}
else l = mid;
}
printf("%.6lf\n", r);
}
return 0;
}