[tyvj1935 Poetize3]导弹防御塔 (二分图多重匹配)

传送门

Description

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

Input

第一行五个正整数N,M,T1,T2,V。
接下来M行每行两个整数,代表入侵者的坐标。
接下来N行每行两个整数,代表防御塔的坐标。

Output

输出一个实数,表示最少需要多少分钟才能击中所有的入侵者,四舍五入保留六位小数。

Sample Input

3 3 30 20 1
0 0
0 50
50 0
50 50
0 1000
1000 0

Sample Output

91.500000

HINT

对于40%的数据,N,M<=20.
对于100%的数据, 1≤N≤50, 1≤M≤50,坐标绝对值不超过10000,T1,T2,V不超过2000.

Solution

二分答案
把入侵者当做左部点,向能在时间内打到它的导弹连边,跑最大匹配
这是多重匹配的一种做法即:拆点

//By Menteur_Hxy
#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define F(i,a,b) for(register int i=(a);i<=(b);i++)
using namespace std;

int read() {
    int x=0,f=1; char c=getchar();
    while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    return x*f;
}

const int N=60;
int n,m,tot;
int vis[N*N],fr[N*N];
double t1,t2,v;
double tim[N][N];
vector <int> V[N];
struct Poi{int x,y;}I[N],D[N];

bool dfs(int x) {
    int siz=V[x].size();
    F(i,0,siz-1) { int v=V[x][i];
        if(!vis[v]) {
            vis[v]=1;
            if(!fr[v]||dfs(fr[v])) {
                // cout<<x<<" "<<v<<endl;
                fr[v]=x;
                return 1;
            }
        }
    }
    return 0;
}

bool jud(double x) {
    tot=0;
    F(i,1,m) V[i].clear();
    F(i,1,m) F(j,1,n) {
        double now=0;
        F(k,0,m) {
            now=k*(t1+t2);
            if(x-(now+t1+tim[i][j])>1e-7) {
                // cout<<i<<" "<<j<<" "<<k<<endl;
                V[i].push_back(j*(m+1)+k-m-1);
            }
            else break;
            // cout<<j*(m+1)+k-m-1<<endl;
        }
    }
    memset(fr,0,sizeof(fr));
    F(i,1,m) {
        memset(vis,0,sizeof(vis));
        if(!dfs(i)) return 0;
    }
    return 1;
}

int main() {
    n=read(),m=read(),t1=read()/60.0,t2=read(),v=read();
    F(i,1,m) I[i].x=read(),I[i].y=read();
    F(i,1,n) D[i].x=read(),D[i].y=read();
    F(i,1,m) F(j,1,n) tim[i][j]=sqrt((I[i].x-D[j].x)*(I[i].x-D[j].x)+(I[i].y-D[j].y)*(I[i].y-D[j].y))/v;
    // F(i,1,m) F(j,1,n) printf("tim[%d][%d]=%lf\n",i,j,tim[i][j]);
    double l=0,r=1000000,ans=r;
    while(r-l>1e-9) {
        double mid=(l+r)/2.0;
        // cout<<mid<<endl;
        if(jud(mid)) ans=min(ans,mid),r=mid;
        else l=mid;
    }
    printf("%.6lf",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ye_xingyu/article/details/81807018