CodeVS2490 导弹防御塔 【二分答案】【匈牙利】

来源:互联网 发布:农村淘宝推广员 编辑:程序博客网 时间:2024/06/05 16:00

【题目描述】
 Freda的城堡——
  “Freda,城堡外发现了一些入侵者!”
  “喵…刚刚探究完了城堡建设的方案数,我要歇一会儿嘛lala~”
  “可是入侵者已经接近城堡了呀!”
  “别担心,rainbow,你看呢,这是我刚设计的导弹防御系统的说~”
  “喂…别卖萌啊……”

  Freda控制着N座可以发射导弹的防御塔。每座塔都有足够数量的导弹,但是每座塔每次只能发射一枚。在发射导弹时,导弹需要T1秒才能从防御塔中射出,而在发射导弹后,发射这枚导弹的防御塔需要T2分钟来冷却。
  所有导弹都有相同的匀速飞行速度V,并且会沿着距离最短的路径去打击目标。计算防御塔到目标的距离Distance时,你只需要计算水平距离,而忽略导弹飞行的高度。导弹在空中飞行的时间就是 (Distance/V) 分钟,导弹到达目标后可以立即将它击毁。
  现在,给出N座导弹防御塔的坐标,M个入侵者的坐标,T1、T2和V,你需要求出至少要多少分钟才能击退所有的入侵者。
【题解】
二分+dinic
我们在发射的防御塔和目标之间连一个(双向)边,跑一边看符不符合就行了。
代码如下:

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const int inf=30000;const int M=1000000;const int N=50;double t[N*N+5][N*N+5];double t1,t2;int x[N+5],y[N+5];int num,head[M+5];bool flag[M+5];int match[M+5];int n,m;double v;struct edge{    int u,v;    int next;    edge(){next=-1;}}ed[M+5];void build(int u,int v){    num++;    ed[num].v=v;    ed[num].next=head[u];    head[u]=num;}bool dfs(int u){    for(int i=head[u];i!=-1;i=ed[i].v)    {        int v=ed[i].v;        if(!flag[v])        {            flag[v]=1;            if(!match[v]||!dfs(match[v]))            {                match[v]=u;                return true;            }        }    }    return false;}bool check(double T){    num=0;    memset(head,-1,sizeof(head));    memset(match,0,sizeof(match));    int d=(d-T)/(t1+t2)+1;    for(int i=1;i<=n;i++)    for(int j=0;j<d;j++)    {        double now=t1+(t1+t2)*j;        for(int k=1;k<=m;k++)        {            if(now+t[i][m]<=T)            {                build(i+j*n,d*n+k);                build(d*n+k,j*n+i);            }        }    }    int ans=0;    for(int i=1;i<=d*n+m;i++)    {        memset(flag,0,sizeof(flag));        if(dfs(1))ans++;    }    return ans>>2==m;}double div(){    double lf=t1,rg=inf;    for(int i=1;i<=40;i++)    {        double mid=(lf+rg)/2.0;        if(check(mid))rg=mid;        else lf=mid;    }    return rg;}double calc(int x1,int y1,int x2,int y2){    return sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));}int main(){    scanf("%d%d%lf%lf%lf",&n,&m,&t1,&t2,&v);    t1/=60.0;    for(int i=1;i<=m;i++)    scanf("%d%d",&x[i],&y[i]);    for(int i=1;i<=n;i++)    {        int a,b;        scanf("%d%d",&a,&b);        for(int j=1;j<=m;j++)        t[i][j]=calc(x[j],y[j],a,b)/v;    }    printf("%.6lf\n",div());    return 0;}
原创粉丝点击