• ZOJ 3460 Missile(二分+二分匹配)


    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, T1, T2 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 N, M, T1, T2 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, T1, T2, V 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
    

    Author: HE, Ningxu
    Contest: ZOJ Monthly, January 2011

    本题首先就是要仔细读懂题目。

    N个导弹基地射击M个目标,每个塔发射一个导弹需要的时间为T1,然后T2时间之后才能发射另外一个导弹。

    此题用二分+二分匹配解决感觉太神奇了~~~~~

    高效的二分,然后用二分匹配,多么美妙啊。

    要扩展为M*N个导弹发射基地。二分时间限制,建图,求最大匹配。

    代码:

    /*
    大致题意:
    
    用n个导弹发射塔攻击m个目标。每个发射架在某个时刻只能为
    一颗导弹服务,发射一颗导弹需要准备t1的时间,一颗导弹从发
    射到击中目标的时间与目标到发射架的距离有关。每颗导弹发
    射完成之后发射架需要t2的时间进入下个发射流程。现在问
    最少需要多少时间可以击毁所有m个目标。
    
    
    大致思路:
    二分枚举这个最大时间的最小值,每次按照这个枚举的时间构出
    二分图,求最大匹配来判定枚举值是否符合要求。
    
    注意单位,T1要除于60转化成分的
    
    */
    
    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    #include<math.h>
    #include<vector>
    using namespace std;
    const double eps=1e-8;
    const int MAXN=2550;
    int linker[MAXN];
    bool used[MAXN];
    vector<int>g[60];
    int uN;
    bool dfs(int u)
    {
        for(int i=0;i<g[u].size();i++)
        {
            if(!used[g[u][i]])
            {
                used[g[u][i]]=true;
                if(linker[g[u][i]]==-1||dfs(linker[g[u][i]]))
                {
                    linker[g[u][i]]=u;
                    return true;
                }
            }
        }
        return false;
    }
    int hungary()
    {
        int u;
        int res=0;
        memset(linker,-1,sizeof(linker));
        for(u=0;u<uN;u++)
        {
            memset(used,false,sizeof(used));
            if(dfs(u))res++;
        }
        return res;
    }
    
    int N,M;
    double  T1,T2,V;
    struct Node
    {
        int x,y;
    };
    Node node1[60],node2[60];
    double d[60][60];
    double tt[MAXN][60];
    
    double dis(Node a,Node b)
    {
        return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    }
    
    void init()
    {
        for(int i=0;i<N;i++)
          for(int j=0;j<M;j++)
            d[i][j]=dis(node1[i],node2[j]);
        for(int k=0;k<M;k++)
          for(int i=0;i<N;i++)
            for(int j=0;j<M;j++)
            {
                tt[i*M+k][j]=k*T2+(k+1)*T1+d[i][j]/V;
            }
        uN=M;
    }
    
    double solve()
    {
        double l=0;
        double r=200000000000.0;
        double mid;
        while(r-l>=eps)
        {
            mid=(l+r)/2;
            for(int i=0;i<M;i++)g[i].clear();
            for(int i=0;i<M*N;i++)
              for(int j=0;j<M;j++)
              {
                  if(tt[i][j]<=mid)g[j].push_back(i);
              }
            if(hungary()==M)
            {
               r=mid;
            }
            else l=mid;
        }
        printf("%.6lf\n",r);
    }
    int main()
    {
        //freopen("in.txt","r",stdin);
        //freopen("out.txt","w",stdout);
        while(scanf("%d%d%lf%lf%lf",&N,&M,&T1,&T2,&V)!=EOF)
        {
            T1/=60;//这个注意,没有除一直得不到答案,纠结
            for(int i=0;i<M;i++)scanf("%d%d",&node2[i].x,&node2[i].y);
            for(int i=0;i<N;i++)scanf("%d%d",&node1[i].x,&node1[i].y);
            init();
            solve();
        }
        return 0;
    }
    人一我百!人十我万!永不放弃~~~怀着自信的心,去追逐梦想
  • 相关阅读:
    C# 调用cmd执行指令
    如何发布 silverlight wcf 简单易学
    C#读取特定目录下的所有文件
    用批处理bat一次安装所有的系统更新补丁
    动态创建datagrid序号
    学习DIV+CSS一个最简单的布局一行三列DIV代码!
    highslide图片查看特效
    相册程序mageVue
    让Apache支持ASP.NET
    ASP.NET四种页面导航方式之比较与选择
  • 原文地址:https://www.cnblogs.com/kuangbin/p/2711866.html
Copyright © 2020-2023  润新知