首页 > 其他分享 >P10936 导弹防御塔 题解

P10936 导弹防御塔 题解

时间:2024-12-25 21:11:48浏览次数:4  
标签:ene int 题解 tow 导弹 防御 P10936 t1 敌人

题目链接

题目大意

城堡有 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; 
}

标签:ene,int,题解,tow,导弹,防御,P10936,t1,敌人
From: https://www.cnblogs.com/hirasawayuii/p/18631400

相关文章

  • P10952 聚会 题解
    题目链接题目大意对于一棵树,求出一个点对于给定的三个点(以下简称$x$,$y$,$z$且可以重复)距离最短。题解对于点的距离,不难想到LCA处理。而对于本题,则有两种情况。第一问三点中有一为另外两个点的祖先时,所求目标点(以下简称$v$)的深度(简称$d_v$)一定在三点深度之间。三......
  • rust-analyzer 引入含有openssl包报错(openssl未找到)问题解决方案
    1.下载openssl编译后的包https://slproweb.com/products/Win32OpenSSL.html选择完全包2.安装注意下面这一步把dll安装到/bin所在的同级目录一路回车,最后的捐款可以不选3.设置环境变量经过实验,主要的环境变量有3个OPENSSL_DIR="C:\ProgramFiles\OpenSSL-Win64"这......
  • ARC101E题解
    前言此片题解大致按照笔者做题思路进行讲解。简要题意有一棵树,树上有偶数个节点。你需要给这些点两两配对,一组已经配对的点会将两点之间的树边进行一次覆盖。一组合法方案需要满足树上所有边都被覆盖至少一次,求合法方案数。数据范围:\(n\le5000\)。思路首先我们去观察题目性......
  • PyTorch 入门指南:安装流程、应用示例与问题解法
    安装PyTorch环境准备确保你的系统安装了Python。PyTorch支持Python3.6及以上版本。可以从Python官方网站(https://www.python.org/)下载并安装。建议使用虚拟环境(如venv或conda)来隔离项目依赖。以conda为例,你可以使用以下命令创建一个新的环境:condacreate-npytorch_env......
  • MySQL占用内存和SWAP问题解决
    背景发现公司的项目部署上,经常出现数据库占用内存很高(接近6G)的情况,而且还出现了SWAP使用到90%左右的水平。所以需要排查数据库使用内存的情况,看数据库为什么使用了这么多内存,而且会不会频繁使用交换空间。要解决的问题:数据库使用高内存数据库使用SWAP解决SWAP空间在......
  • [BZOJ4771] 七彩树 题解
    好题,又学两个思路。先把问题变简单一点,去掉深度限制,那么有两种做法:经典的前驱后继转化到二维数点。颜色相同的点按\(dfs\)序排序,每个点\(+1\),相邻两点\(lca-1\)。转化为区间求和。第二种相对实现简单。假如加上深度,我们可以离线问题,按深度顺序加点。要在线的话,只......
  • CF2043C 题解
    CF2043C题解题意给定一个除了\(-1,1\)之外,最多存在一个\(x,x\in[-10^9,10^9]\)的数的序列,求其子段和的所有可能值,从小到大输出。分析很容易就去思考如何从这个特殊的\(x\)入手。于是先排除这个特例,考虑全都是\(1,-1\)的情形,那么顺序从左到右不断加入\(a_i\),可以发现......
  • P6779 [Ynoi2009] rla1rmdq 题解
    Description给定一棵\(n\)个节点的树,树有边权,与一个长为\(n\)的序列\(a\)。定义节点\(x\)的父亲为\(fa(x)\),根\(rt\)满足\(fa(rt)=rt\)。定义节点\(x\)的深度\(dep(x)\)为其到根简单路径上所有边权和。有\(m\)次操作:1lr:对于\(l\lei\ler\),\(a_i\lef......
  • 【Web】2024“国城杯”网络安全挑战大赛决赛题解(全)
    最近在忙联通的安全准入测试,很少有时间看CTF了,今晚抽点时间回顾下上周线下的题(期末还没开始复习......
  • 题解 P9885【[Qingdao18A] Sequence and Sequence】
    具体数学还在发力!题目描述考虑下列两个序列\(P\)和\(Q\)。我们用\(P(i)\)表示序列\(P\)中的第\(i\)个元素,用\(Q(i)\)表示序列\(Q\)中的第\(i\)个元素:序列\(P\)是一个已排序的序列,其中,对于所有\(k\in\mathbb{Z^+}\),\(k\)在序列\(P\)中出现\((k+1)\)......