zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    Vue-router路由传参三种方法及区别
    Vue.mixins混入方法的使用
    移动端自适应方案—rem布局
    JS获取页面宽度高度及Vue页面自适应方案
    Vue实现文件的上传与下载
    Prometheus第六篇:prometheus高可用架构
    Prometheus第五篇:prometheus告警规则配置和通过alertmanager精准发送告警
    Prometheus第四篇:prometheus服务发现方式解析
    Prometheus第三篇:prometheus.yml配置解析
    Prometheus第二篇:Prometheus部署
  • 原文地址:https://www.cnblogs.com/mcggvc/p/12627419.html
Copyright © 2011-2022 走看看