Missile
Time Limit: 2 Seconds Memory Limit: 65536 KB
You control N missile launching towers. Every tower has enough missiles, but for each tower only one missile can be launch at the same time. Before the launching, every missile need T1 seconds to leave the tower. Assume that all the missiles have the same speed V, and it would fly along the shortest path to the target. You can just consider the horizontal distance and ignore the height. You can consider the time equal to distance / V (minutes). The missile can immediately destroy the target when it reached. Besides, for the same tower, after launching a missile, it need T2 minutes to prepare for the next one.
Now, give you the coordinate position of N missile launching towers and M targets, T1, T2 and V, you should find the minimum minutes to destroy all the targets.
Input
The input will consist of about 10 cases. The first line of each case contains five positive integer numbers N, M, T1, T2 and V, decribed as above. The next M lines contains two integer numbers indicating the coordinate of M targets. The continueing N lines contains two integer numbers indicating the coordinate of N towers.
To all the
cases, 1 ≤ N ≤ 50, 1 ≤ M ≤ 50
The absolute value of all the
coordinates will not exceed 10000, T1,
T2, V will not exceed 2000.
Output
For each case, the output is only one line containing only one real number
with six digits precision (after a decimal point) indicating the minimum minutes
to destroy all the targets.
Sample Input
3 3 30 20 1 0 0 0 50 50 0 50 50 0 1000 1000 0
Sample Output
91.500000
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <cmath> #define INF 0x3f3f3f3f #define maxn 5000 #define maxm 500000 using namespace std; int head[maxn], cur[maxn], cnt; int dist[maxn], vis[maxn]; struct node { int u, v, cap, flow, next; }; struct NODE{ double x, y; }; node edge[maxm]; NODE tower[60]; NODE target[60]; int N, M; double T1, T2, V; double map[60][60]; double Time[3000][60]; double change(NODE a, NODE b){ return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)); } void init(){ cnt = 0; memset(head, -1, sizeof(head)); } void add(int u, int v, int w){ node E1 = {u, v, w, 0, head[u]}; edge[cnt] = E1; head[u] = cnt++; node E2 = {v, u, 0, 0, head[v]}; edge[cnt] = E2; head[v] = cnt++; } void getmap(double max_min){ int i, j; for(i = 1; i <= N * M; ++i) add(0, i, 1); for(i = N * M + 1; i <= N * M + M; ++i) add(i, N * M + M + 1, 1); for(i = 1; i <= N * M; ++i) for(j = 1; j <= M; ++j) if(Time[i][j] <= max_min) add(i, j + N * M, 1); } bool BFS(int st, int ed){ queue<int>q; memset(vis, 0, sizeof(vis)); memset(dist, -1, sizeof(dist)); q.push(st); vis[st] = 1; dist[st] = 0; while(!q.empty()){ int u = q.front(); q.pop(); for(int i = head[u]; i != -1; i = edge[i].next){ node E = edge[i]; if(!vis[E.v] && E.cap > E.flow){ vis[E.v] = 1; dist[E.v] = dist[u] + 1; if(E.v == ed) return true; q.push(E.v); } } } return false; } int DFS(int x, int ed, int a){ if(a == 0 || x == ed) return a; int flow = 0, f; for(int &i = cur[x]; i != -1; i =edge[i].next){ node &E = edge[i]; if(dist[E.v] == dist[x] + 1 && (f = DFS(E.v, ed, min(a, E.cap - E.flow))) > 0){ E.flow += f; edge[i ^ 1].flow -= f; flow += f; a -= f; if(a == 0) break; } } return flow; } int maxflow (int st, int ed){ int flowsum = 0; while(BFS(st, ed)){ memcpy(cur, head, sizeof(head)); flowsum += DFS(st, ed, INF); } return flowsum; } int main (){ while(scanf("%d%d%lf%lf%lf", &N, &M, &T1, &T2, &V) != EOF){ T1 = T1 / 60; int i, j, k; for(j = 1; j <= M; ++j) scanf("%lf%lf", &target[j].x, &target[j].y); for(i = 1; i <= N; ++i) scanf("%lf%lf", &tower[i].x, &tower[i].y); for(i = 1; i <= N; ++i) for(j = 1; j <= M; ++j) map[i][j] = change(tower[i], target[j]); for(i = 1; i <= N; ++i) for(k = 1; k <= M; ++k){ for(j = 1; j <= M; ++j) Time[(i - 1) * M + k][j] = T1 * k + T2 * (k - 1) + map[i][j] / V; } double l = 0.0, r = 200000000000.0, mid; while(r - l >= 1e-8){ mid = (l + r) / 2; init(); getmap(mid); if(maxflow(0, N * M + M + 1) >= M) r = mid; else l = mid; } printf("%.6lf\n", r); } return 0; }