contest hunter 6803 导弹防御塔

没什么好写的。写写这题吧

拆点,把一个防御塔拆成m个,表示第i次攻击。瞎yy就好啊

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

struct node
{
    int x,y,next;
}a[210000];int len,last[3100];
void ins(int x,int y)
{
    len++;
    a[len].x=x;a[len].y=y;
    a[len].next=last[x];last[x]=len;
}
int tim,v[110],match[110];
bool findmuniu(int x)
{
    for(int k=last[x];k;k=a[k].next)
    {
        int y=a[k].y;
        if(v[y]!=tim)
        {
            v[y]=tim;
            if(match[y]==0||findmuniu(match[y])==true)
            {
                match[y]=x;
                return true;
            }
        }
    }
    return false;
}

int n,m;double T1,T2,V;
struct point{double x,y;}p[110],q[110];
double getdis(int i,int j)
{
    return sqrt((p[i].x-q[j].x)*(p[i].x-q[j].x)+(p[i].y-q[j].y)*(p[i].y-q[j].y))/V;
}
bool check(double mid)
{
    len=0;memset(last,0,sizeof(last));
    for(int i=1;i<=n;i++)
    {
        bool bk=true;
        for(int u=1;u<=m;u++)
        {
            bk=false;
            for(int j=1;j<=m;j++)
                if(u*T1+(u-1)*T2+getdis(i,j)<=mid)
                    ins((u-1)*n+i,j), bk=true;
            if(bk==false)break;
        }
    }
    int ans=0;
    tim=0;memset(v,0,sizeof(v));
    memset(match,0,sizeof(match));
    for(int i=1;i<=n;i++)
    {
        int u=1;
        for(int u=1;u<=m;u++)
        {
            tim++;
            if(findmuniu((u-1)*n+i))tim++,ans++;
            else break;
        }
    }
    return ans==m;
}
int main()
{
    scanf("%d%d%lf%lf%lf",&n,&m,&T1,&T2,&V);T1/=60;
    for(int i=1;i<=m;i++)scanf("%lf%lf",&q[i].x,&q[i].y);
    for(int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
    
    double l=0,r=100000;
    while(r-l>1e-8)
    {
        double mid=(l+r)/2;
        if(check(mid))r=mid;
        else l=mid;
    }
    printf("%.6lf\n",l);
    return 0;
}

 

posted @ 2018-08-27 15:19  AKCqhzdy  阅读(231)  评论(0编辑  收藏  举报