zoj3460

本文探讨了在有限时间内利用导弹塔台优化击中多个目标的策略,通过二分法和二分图理论,实现最小时间完成所有目标的摧毁。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3460

Missile

Time Limit: 2 Seconds       Memory Limit: 65536 KB

You control N missile launching towers. Every tower has enough missiles, but for each tower only one missile can be launch at the same time. Before the launching, every missile need T1 seconds to leave the tower. Assume that all the missiles have the same speed V, and it would fly along the shortest path to the target. You can just consider the horizontal distance and ignore the height. You can consider the time equal to distance / V (minutes). The missile can immediately destroy the target when it reached. Besides, for the same tower, after launching a missile, it need T2 minutes to prepare for the next one.

Now, give you the coordinate position of N missile launching towers and M targets, T1T2 and V, you should find the minimum minutes to destroy all the targets.

Input

The input will consist of about 10 cases. The first line of each case contains five positive integer numbers NMT1T2 and V, decribed as above. The next M lines contains two integer numbers indicating the coordinate of M targets. The continueing N lines contains two integer numbers indicating the coordinate of N towers.
To all the cases, 1 ≤ N ≤ 50, 1 ≤ M ≤ 50
The absolute value of all the coordinates will not exceed 10000, T1T2V will not exceed 2000.

Output

For each case, the output is only one line containing only one real number with six digits precision (after a decimal point) indicating the minimum minutes to destroy all the targets.

Sample Input
3 3 30 20 1
0 0
0 50
50 0
50 50
0 1000
1000 0
Sample Output
91.500000
/**
zoj3460 二分+二分图
题目大意:有n个塔台,m个目标,每个塔台可以发射导弹到目标,发射需要时间t1,导弹飞行速度为v,发射过后塔台需要准备t2的时间才能
          发射下一枚导弹,问最少用时多少可以击中全部目标
解题思路:二分枚举这个最大时间的最小值,每次按照这个枚举的时间构出
          二分图,求最大匹配来判定枚举值是否符合要求。
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
using namespace std;

int n,m;
double t1,t2,v;

struct note
{
    int x,y;
} tor[56],tar[56];

double get_leng(note a,note b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
double a[2505][55];

int linker[2505],w[2505][55];
bool used[2505];
bool dfs(int u)
{
    int v;
    for(int v=0; v<m; v++)
    {
        if(w[u][v]&&!used[v])
        {
            used[v]=true;
            if(linker[v]==-1||dfs(linker[v]))
            {
                linker[v]=u;
                return true;
            }
        }
    }
    return false;
}

int hungary()
{
    int res=0;
    int u;
    memset(linker,-1,sizeof(linker));
    for(u=0; u<n*m; u++)
    {
        memset(used,0,sizeof(used));
        if(dfs(u))res++;
    }
    return res;
}

void solve()
{
    for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
        {
            for(int k=0; k<m; k++)
            {
                a[m*j+i][k]=(i+1)*t1+i*t2+get_leng(tor[j],tar[k])/v;
            }
        }
    }
    double l=0.0,r=200000000000.0,mid;
    while(r-l>1e-9)
    {
        mid=(l+r)/2.0;
        memset(w,0,sizeof(w));
        for(int i=0; i<m*n; i++)
        {
            for(int j=0; j<m; j++)
            {
                if(a[i][j]<=mid)
                    w[i][j]=1;
            }
        }
        if(hungary()==m)
        {
            r=mid;

        }
        else
            l=mid;
    }
    printf("%.6lf\n",r);
}

int main()
{
    while(~scanf("%d%d%lf%lf%lf",&n,&m,&t1,&t2,&v))
    {
        t1/=60.0;
        for(int i=0; i<m; i++)
        {
            scanf("%d%d",&tar[i].x,&tar[i].y);
        }
        for(int i=0; i<n; i++)
        {
            scanf("%d%d",&tor[i].x,&tor[i].y);
        }
        solve();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值