CH6803 导弹防御塔(二分图匹配-多重匹配)

链接: 6803 导弹防御塔
根据题意,二分最少的时间,然后连边看看能不能全部匹配。
每个炮塔能发射多发炮弹,所以将每个炮塔拆成多个炮弹,让怪和炮弹相连,对于第 i 个怪和第 j 个炮塔的第 k 个炮弹,打击所需的时间为\(dis(i, j) / v + k * t_1 + (k - 1) * t_2)\) (第 k 个炮弹发射出之前要等k个\(t_1\)和 k - 1 个\(t_2\))。
代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 55;
const int M = 2505;
const double e = 1e-9;
int n, m, t;
double t1, t2, v;
struct node {
	double x, y;
} a[N], b[N], c[M];
int nextt[M * N], to[M * N], head[N], cnt = 0;
int match[M], tot = 0;
bool vis[M];
void add(int x, int y) {
	nextt[++cnt] = head[x]; 
	to[cnt] = y; head[x] = cnt;
}
double dist(int i, int j) {
	double tmp1 = (a[i].x - b[j].x) * (a[i].x - b[j].x);
	double tmp2 = (a[i].y - b[j].y) * (a[i].y - b[j].y);
	double dist = sqrt(tmp1 + tmp2);
	return dist;
}
void update(double p) {
	cnt = 0;
	memset(head, 0, sizeof(head));
	for(int i = 1; i <= m; i++) {
		for(int j = 1; j <= n; j++) {
			c[(i - 1) * n + j].x = j;
			c[(i - 1) * n + j].y = i * t1 + (i - 1) * t2;
		}
	}
	for(int i = 1; i <= m; i++) {
		for(int k = 1; k <= t; k++) {
				if(dist(i, c[k].x) / v + c[k].y <= p) add(i, k);
		}
	}
}
bool dfs(int x) {
	for(int i = head[x]; i; i = nextt[i]) {
		int y = to[i];
		if(vis[y]) continue;
		vis[y] = true;
		if(!match[y] or dfs(match[y])) {
			match[y] = x; return true;
		}
	}
	return false;
}
bool check(double p) {
	update(p);
	int ans = 0;
	memset(match, 0, sizeof(match));
	for(int i = 1; i <= m; i++) {
		memset(vis, 0, sizeof(vis));
		if(!dfs(i)) return false;
	}
	return true;
}
int main() {
//	freopen("data.in", "r", stdin);
	scanf("%d%d%lf%lf%lf", &n, &m, &t1, &t2, &v);
	t1 /= 60.0; t = n * m;
	for(int i = 1; i <= m; i++) {
		scanf("%lf%lf", &a[i].x, &a[i].y);
	}
	for(int i = 1; i <= n; i++) {
		scanf("%lf%lf", &b[i].x, &b[i].y);
	}
	double l = t1, r = 60000.0;
	while(r - l > e) {
		double mid = (l + r) / 2.0;
		if(check(mid)) r = mid;
		else l = mid;
	}
	printf("%.6lf", l);
	return 0;
}
posted @ 2020-04-03 16:51  Mcggvc  阅读(119)  评论(0编辑  收藏  举报