• JoyOI1935 导弹防御塔


    原题链接

    首先可以二分答案,然后考虑检验答案。
    我们可以对炮塔进行拆点,即能发射(x)颗导弹就拆成(n imes x)个点,作为一个集合,另一个集合则是(m)个侵入者,然后对于能在剩余时间攻击到侵入者的炮弹和该侵入者连边,然后跑匈牙利或网络流求二分图最大匹配即可(本质是多重匹配,使用拆点法)。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    const int N = 55;
    const int M = 1e6 + 10;
    const int K = 1e5 + 10;
    struct dd {
    	double x, y;
    };
    dd a[N], b[N];
    int fi[K], di[M], ne[M], mtc[K], l, t_2, n, m;
    double dis[N][N], t_1;
    bool v[K];
    inline int re()
    {
    	int x = 0;
    	char c = getchar();
    	bool p = 0;
    	for (; c < '0' || c > '9'; c = getchar())
    		p |= c == '-';
    	for (; c >= '0' && c <= '9'; c = getchar())
    		x = x * 10 + c - '0';
    	return p ? -x : x;
    }
    inline void add(int x, int y)
    {
    	di[++l] = y;
    	ne[l] = fi[x];
    	fi[x] = l;
    }
    bool dfs(int x)
    {
    	int i, y;
    	for (i = fi[x]; i; i = ne[i])
    		if (!v[y = di[i]])
    		{
    			v[y] = 1;
    			if (!mtc[y] || dfs(mtc[y]))
    			{
    				mtc[y] = x;
    				return true;
    			}
    		}
    	return false;
    }
    bool judge(double mid)
    {
    	int i, j, s = 0, k = 0;
    	double T = mid;
    	memset(fi, 0, sizeof(fi));
    	memset(mtc, 0, sizeof(mtc));
    	l = 0;
    	while (T >= t_1)
    	{
    		T -= t_1;
    		k++;
    		for (i = 1; i <= m; i++)
    			for (j = 1; j <= n; j++)
    				if (dis[j][i] <= T)
    					add(i, (k - 1) * n + j);
    		T -= t_2;
    	}
    	for (i = 1; i <= m; i++)
    	{
    		memset(v, 0, sizeof(v));
    		if (dfs(i))
    			s++;
    	}
    	return !(s ^ m);
    }
    int main()
    {
    	int i, j, x, y, V;
    	double l, r = 3e4, mid;
    	n = re();
    	m = re();
    	l = t_1 = re() * 1.0 / 60;
    	t_2 = re();
    	V = re();
    	for (i = 1; i <= m; i++)
    	{
    		a[i].x = re();
    		a[i].y = re();
    	}
    	for (i = 1; i <= n; i++)
    	{
    		x = re();
    		y = re();
    		for (j = 1; j <= m; j++)
    			dis[i][j] = sqrt(1.0 * (x - a[j].x) * (x - a[j].x) + 1.0 * (y - a[j].y) * (y - a[j].y)) / V;
    	}
    	while (l + 1e-7 < r)
    	{
    		mid = (l + r) / 2;
    		if (judge(mid))
    			r = mid;
    		else
    			l = mid;
    	}
    	printf("%.6f", r);
    	return 0;
    }
    
  • 相关阅读:
    从零开始学Flask框架-002
    从零开始学Flask框架-001
    js 数组去重 + 数组内元素为对象去重
    使用npx 搭建项目-继续爬坑
    使用nuxt.js+koa2创建项目-继续爬坑
    nuxt.js 初次运行报错 -- 爬坑全过程
    VueRouter配置引入
    MySqlHelper.ExecuteReader 爬坑
    javascript 解析,设置,检测cookie
    python sqlite数据库操作小坑
  • 原文地址:https://www.cnblogs.com/Iowa-Battleship/p/9642609.html
Copyright © 2020-2023  润新知