码迷,mamicode.com
首页 > Windows程序 > 详细

AcWing 374. 导弹防御塔

时间:2021-02-08 12:33:02      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:str   double   string   ring   现在   clu   space   相同   ret   

题目链接:AcWing 374. 导弹防御塔

题面:

? Freda的城堡遭到 \(M\) 个入侵者的袭击!Freda控制着 \(N\) 座导弹防御塔,每座塔有足够数量的导弹,但每次只能发射一枚。在发射导弹时,导弹需要 \(T1\) 秒才能从防御塔中射出,而在发射导弹后,发射这枚导弹的防御塔需要 \(T2\) 分钟来冷却。

? 所有导弹都有相同的匀速飞行速度 \(V\),并且会沿着距离最短的路径去打击目标。计算防御塔到目标的距离Distance时,你只需要计算水平距离,而忽略导弹飞行的高度。导弹在空中飞行的时间就是 (\(Distance/V\)) 分钟,导弹到达目标后可以立即将它击毁。

? 现在,给出 N 座导弹防御塔的坐标,\(M\) 个入侵者的坐标,\(T1\) , \(T2\)\(V\) 。因为Freda的小伙伴Rainbow就要来拜访城堡了,你需要求出至少多少分钟才能击退所有的入侵者。

数据范围:

\(1\leq N,M\leq 50\),坐标绝对值 \(\leq 10000\)\(T1,T2,V\leq 2000\)

思路:

? 开始对算法不熟悉的时候很容易思路想歪。

? 注意到数据范围很小,考虑将每一枚导弹和入侵者二分图匹配,由于答案具有单调性,且不方便直接计算,对其进行二分。

? 为了写起来方便,我们构造 \(N*M\) 枚导弹作为右部节点,把 \(M\) 个入侵者作为左部节点,每一座导弹防御塔都可以依次发射 \(M\) 枚导弹,如果第 \(i\) 座塔的第 \(j\) 枚导弹可以在 \(mid\) 时间内到达侵略者 \(k\) ,则在节点 \(i*m+j+m\) 和节点 \(k\) 之间连无向边。 \((0\leq i< N,0\leq j,k<M)\) ,建图后用匈牙利算法判断每个左部点是否都能找到匹配,可以则 \(r=mid\) ,否则 \(l=mid\)

Code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,b,a) for(int i=b;i>=a;i--)
#define mem(a,b) memset(a,b,sizeof(a))
#define N 2600
#define M 250100
#define eps 1e-8
using namespace std;
int head[N],to[M],nxt[M];
int cnt,n,m,t2,v;
int a[55][2],b[55][2],match[N];
double t1;  
bool vis[N];
void init(){mem(head,-1),cnt=-1,mem(match,-1);}
void add_e(int a,int b){
    nxt[++cnt]=head[a],head[a]=cnt,to[cnt]=b;
}
double dis(double x1,double y1,double x2,double y2){
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
bool dfs(int x){
    for(int i=head[x],y;~i;i=nxt[i]){
        if(vis[y=to[i]])continue;
        vis[y]=true;
        if(match[y]==-1||dfs(match[y])){
            match[y]=x; return true;
        }
    }
    return false;
}
bool check(double mid){
    init();
    rep(i,0,n-1)rep(j,0,m-1)rep(k,0,m-1){
        if(dis(a[k][0],a[k][1],b[i][0],b[i][1])/v+j*(t1+t2)+t1<=mid)
            add_e(k,i*m+j+m),add_e(i*m+j+m,k);
    }
    rep(i,0,m-1){
        mem(vis,false);
        if(!dfs(i))return false;
    }
    return true;
}
int main(){
    cin>>n>>m>>t1>>t2>>v;
    t1/=60;
    rep(i,0,m-1)cin>>a[i][0]>>a[i][1];
    rep(i,0,n-1)cin>>b[i][0]>>b[i][1];
    double l=t1,r=300000,mid;
    while(l+eps<r){
        mid=(l+r)*0.5;
        if(check(mid))r=mid;
        else l=mid;
    }
    printf("%.6f\n",l);
    return 0;
}

AcWing 374. 导弹防御塔

标签:str   double   string   ring   现在   clu   space   相同   ret   

原文地址:https://www.cnblogs.com/Neal-lee/p/14385974.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!