题目链接

题目大意

城堡有 m 个敌人、n 个能发射导弹的防御塔。导弹的速度固定,都为 v。导弹需要 T1 秒发射,T2 分钟冷却,还需要防御塔到敌人距离的 dis/v 的时间。给定防御塔和敌人的坐标,求需要多少分钟能够消灭所有敌人。

推导思路

如果短的时间能够消灭所有敌人,则长的也一定能。所以答案具有单调性,可以通过二分答案将求解转为判定。而该问题的判定,类似于一个导弹与敌人互相匹配的问题。对于这个问题,二分图的最大匹配就是一个不错的求解思路。

二分图最大匹配

细节实现

由于每个导弹可以多次匹配,所以转化为多次匹配的拆点做法。设左部为敌人,右部为导弹,遍历连边即可。连边的细节较多,在下面的代码中有注释体现。

代码

// Problem: P10936 导弹防御塔
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P10936
// Memory Limit: 512 MB
// Time Limit: 1000 ms
// Date: 2024-12-20 18:43:22
//
// Powered by CP Editor (https://cpeditor.org) #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define mst(x, y) memset(x, y, sizeof(x))
#define pii pair<int, int>
#define fi first
#define se second
#define mp(x, y) make_pair(x, y) const int N = 55, M = 200005, inf = 0x3f3f3f3f; //记得空间开足够大,可以在不影响时间的情况下(memset)大概估一下
const double eps = 1e-8; int n, m, idx;
int vis[M], mat[M], hd[M], ver[M], nxt[M];
double t1, t2, v;
struct pos{
int x, y;
}ene[N], tow[N]; void add(int x, int y){
nxt[++idx] = hd[x];
ver[idx] = y;
hd[x] = idx;
}
double cal(int i, int j){ //计算导弹飞行到敌人时间
return sqrt((ene[i].x-tow[j].x)*(ene[i].x-tow[j].x)+(ene[i].y-tow[j].y)*(ene[i].y-tow[j].y))/v;
}
bool dfs(int x){ //二分图最大匹配增广路算法板子
for(int i = hd[x];i;i = nxt[i]){
int y = ver[i];
if(vis[y]) continue;
vis[y] = 1;
if(!mat[y] || dfs(mat[y])){
mat[y] = x;
return true;
}
}
return false;
}
bool check(double x){ //x为最大时间
mst(mat, 0);mst(hd, 0);idx = 0; //最大匹配+链式前向星存图初始化
int maxk = min(m, (int)floor((x+t2)/(t1+t2))); //maxk为最大时间内导弹最多的发生数(因为求的是最多次数,所以不考虑时间)
for(int i = 1;i <= m;i++){ //遍历敌人
for(int j = 1;j <= n;j++){ //遍历防御塔
for(int k = 1;k <= maxk;k++){ //遍历导弹个数
if(double(cal(i, j)+(k-1)*(t1+t2)+t1) > x) continue; //判断对于第i个敌人第j个防御塔的第k个导弹,是否能在最大时间限制内发射
//这里需要详细注意一下,(j-1)*maxk+k即为第j个防御塔的第k个导弹编号,但导弹编号会和敌人编号重复,所以将导弹编号加上敌人个数防止重复
add(i, m+(j-1)*maxk+k);
add(m+(j-1)*maxk+k, i); //连双向边
}
}
}
for(int i = 1;i <= m;i++){
mst(vis, 0);
if(!dfs(i)) return false; //如果有敌人无法匹配到导弹(即不能在最大时间内被杀死),则直接返回false
}
return return;
}
void init(){
cin >> n >> m >> t1 >> t2 >> v;
t1 /= 60;//t1单位为秒,要转化为分钟
for(int i = 1;i <= m;i++) cin >> ene[i].x >> ene[i].y;
for(int i = 1;i <= n;i++) cin >> tow[i].x >> tow[i].y;
}
void solve(){
double l = 0, r = 100000, mid;
while(r-l >= eps){//实数二分
mid = (l+r)/2;
if(check(mid)) r = mid;
else l = mid;
}
printf("%.6lf", l);
} int main(){
init();
solve();
return 0;
}

P10936 导弹防御塔 题解的更多相关文章

  1. 「Poetize3」导弹防御塔

    描述 Description Freda控制着N座可以发射导弹的防御塔.每座塔都有足够数量的导弹,但是每座塔每次只能发射一枚.在发射导弹时,导弹需要T1秒才能从防御塔中射出,而在发射导弹后,发射这枚导 ...

  2. CH6803 导弹防御塔

    6803 导弹防御塔 0x60「图论」例题 背景 Freda的城堡-- "Freda,城堡外发现了一些入侵者!" "喵...刚刚探究完了城堡建设的方案数,我要歇一会儿嘛l ...

  3. Codevs2490 导弹防御塔

    2490 导弹防御塔 2490 导弹防御塔 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master         题目描述 Description Freda的城堡—— ...

  4. bzoj3035: 导弹防御塔

    Description Freda的城堡——“Freda,城堡外发现了一些入侵者!”“喵...刚刚探究完了城堡建设的方案数,我要歇一会儿嘛lala~”“可是入侵者已经接近城堡了呀!”“别担心,rain ...

  5. [tyvj1935 Poetize3]导弹防御塔 (二分图多重匹配)

    传送门 Description Freda控制着N座可以发射导弹的防御塔.每座塔都有足够数量的导弹,但是每座塔每次只能发射一枚.在发射导弹时,导弹需要T1秒才能从防御塔中射出,而在发射导弹后,发射这枚 ...

  6. 【NOIP2013模拟】导弹防御塔

    题目 Freda的城堡-- "Freda,城堡外发现了一些入侵者!" "喵...刚刚探究完了城堡建设的方案数,我要歇一会儿嘛lala~" "可是入侵者 ...

  7. contest hunter 6803 导弹防御塔

    没什么好写的.写写这题吧 拆点,把一个防御塔拆成m个,表示第i次攻击.瞎yy就好啊 #include<cstdio> #include<iostream> #include&l ...

  8. 【CH6803】导弹防御塔

    题目大意:给定 N 座塔,M 个怪物,每座塔一次可以发射一枚导弹,发射导弹有发射时间和冷却时间,每座塔和每只怪物有自己的二维坐标,所有导弹有一个共同的速度,求至少需要多长时间才能将所有怪物消灭. 题解 ...

  9. JoyOI1935 导弹防御塔

    原题链接 首先可以二分答案,然后考虑检验答案. 我们可以对炮塔进行拆点,即能发射\(x\)颗导弹就拆成\(n\times x\)个点,作为一个集合,另一个集合则是\(m\)个侵入者,然后对于能在剩余时 ...

  10. joyoi1935 「Poetize3」导弹防御塔

    #include <iostream> #include <cstring> #include <cstdio> #include <queue> #i ...

随机推荐

  1. Android复习(三)清单文件中的元素——>application

    <application> 语法: <application android:allowTaskReparenting=["true" | "false ...

  2. F450 APM2.8 自组无人机手记

    由于是初次接触无人机,外加自组需要焊接,做了一些前期的心理建设.但是过程还是异常艰难.(不过,实际操作也就焊20个焊点左右,基本就组装起来了,操作并不复杂) 自组APM无人机是想学习Ardupilot ...

  3. nodejs redis 小试牛刀

    一.环境安装 书接上文,浅学Redis之后,服务器已经安装Redis了,用 nodejs 链接 redis 之前,先安装 nodejs 环境. 1.安装fnm (1)压缩包fnm-linux.zip搞 ...

  4. php几种常用的算法

    1 <?php 2 3 // 选择排序 4 5 function select_sort($arr) 6 7 { 8 9 $count = count($arr); 10 11 for ($i ...

  5. SyncOOD:增加OOD目标检测鲁棒性,自动化数据助您一臂之力 | ECCV'24

    本文是对公开论文的核心提炼,而非直接翻译,旨在进行学术交流.如有任何侵权问题,请及时联系号主以便删除. 来源:晓飞的算法工程笔记 公众号,转载请注明出处 论文: Can OOD Object Dete ...

  6. 全网最适合入门的面向对象编程教程:58 Python字符串与序列化-序列化Web对象的定义与实现

    全网最适合入门的面向对象编程教程:58 Python 字符串与序列化-序列化 Web 对象的定义与实现 摘要: 如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML\YAM ...

  7. 每秒550万亿次算力!打破世界纪录!中国造全球首例纯电驱全尺寸人形机器人!直击全球最快人形机器人“天工”The world's first purely electric humanoid robot

    地址: https://www.youtube.com/watch?v=uRc-885NpD4

  8. .NET现在可以做什么,有哪些公司在用的?

    前言 本文大姚和大家一起来分析一下.NET现在可以做什么,.NET未来的发展趋势在哪,有哪些公司在使用的. .NET简单介绍 .NET是一个开源(MIT License).免费.跨平台的开发人员平台框 ...

  9. 多校A层冲刺NOIP2024模拟赛08 排列

    多校A层冲刺NOIP2024模拟赛08 排列 一种连续段 dp 的解法. 题面 小 Y 最近在研究组合数学,他学会了如何枚举排列. 小 Z 最近在研究数论,他学会了求最大公约数. 于是小 Y 和小 Z ...

  10. Spring3.0核心组件的源码简单分析

    前言 本文结合Spring3.0的源码进行简单的介绍,这里的核心组件不是我们常见所谓的IOC和AOP,而是以Spring3.0发布的开发包为切入点,当然Spring3.0以后的各个版本基本上差不多,思 ...