zoj3460Missile【二分图最大匹配限制】

来源:互联网 发布:汶川地震知乎 编辑:程序博客网 时间:2024/05/19 16:23

Description

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 needT1 seconds to leave the tower. Assume that all the missiles have the same speedV, 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 andM 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 numbersN, M, T1, T2 and V, decribed as above. The nextM lines contains two integer numbers indicating the coordinate of M targets. The continueingN 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 10 00 5050 050 500 10001000 0

Sample Output

91.500000

题意:m个目标,n个炮台,坐标都已知,每个炮台发射导弹都需要准备时间t2,导弹在炮筒里需要时间t1(只有这个数是秒!!!其他的时间是分钟!!!!),只计算导弹运动的水平水平时间,速度都是v。问至少多少时间把所有目标都干掉==

超级脑洞题~。~  最最让我们束手无策的是t1,t2的处理,考虑到数据范围只有50*50,很有可能是把数据分开,既然要用到t1,t2,我们想到把n个炮台拆成n*m炮台,把t1,t2加到每个炮台里面,记录时间的二维数组值就是每个实际炮台第几次发射发射到哪个目标所需要的时间,二分最大值,跑二分图,匹配是m的成立。

这种查找方法到时很常见,但是,数组第二维不是n*m 开到60就够了!!!要不tle

#include <iostream>#include <stdio.h>#include <string.h>#include<cmath>#define inf 0x3f3f3f3fusing namespace std;const int MAXN=3000;int uN,vN;//u,v数目int g[MAXN][MAXN];int linker[MAXN];bool used[MAXN];bool dfs(int u)//从左边开始找增广路径{    int v;    for(v=0;v<vN;v++)//这个顶点编号从0开始,若要从1开始需要修改      if(g[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<uN;u++)    {        memset(used,0,sizeof(used));        if(dfs(u)) res++;    }    return res;}struct node{    double x,y;}num1[60],num2[60];double Time[3000][60];int n,m;double t1,t2,v;double dist[60][60];int main(){  //  freopen("cin.txt","r",stdin);    //freopen("out.txt","w",stdout);    while(~scanf("%d%d%lf%lf%lf",&n,&m,&t1,&t2,&v))    {        t1/=60.0;///!!!        for(int i=0;i<m;i++)scanf("%lf%lf",&num1[i].x,&num1[i].y);//这里之前笔误写成了num2        for(int i=0;i<n;i++)scanf("%lf%lf",&num2[i].x,&num2[i].y);        for(int i=0;i<n;i++)//tower            for(int j=0;j<m;j++)//target            {                dist[i][j]=sqrt((num1[j].x-num2[i].x)*(num1[j].x-num2[i].x)+(num1[j].y-num2[i].y)*(num1[j].y-num2[i].y))/v;               // printf("i=%d,j=%d,dist=%lf\n",i,j,dist[i][j]);这里之前i,j写反了            }        for(int i=0;i<m;i++)//time        {            for(int j=0;j<n;j++)//target            {                for(int k=0;k<m;k++)//tower                {                    Time[m*j+i][k]=dist[j][k]+(i+1)*t1+i*t2;                   // printf("i=%d,j=%d,k=%d,Time=%lf,dist=%lf\n",i,j,k,Time[m*j+i][k],dist[j][k]);                }            }        }        double l=0.0,r=200000000000.0,mid;        uN=n*m,vN=m;        while(r-l>1e-8)        {            mid=(l+r)/2.0;            memset(g,0,sizeof(g));            for(int i=0;i<m*n;i++)                for(int j=0;j<m;j++)                    if(Time[i][j]<=mid) g[i][j]=1;            int tmp=hungary();        //    printf("tmp=%d\n",tmp);            if(tmp==m) r=mid;            else l=mid;           // printf("l=%lf,mid=%lf,r=%lf\n",l,mid,r);        }        printf("%.6lf\n",r);    }    return 0;}


0 0
原创粉丝点击