导弹防御塔
导弹有:发射时间/冷却时间/到达时间 给定若干个防御塔和目标 问最少多少时间能够消灭所有敌人
最多最少问题先看看二分答案!!!
二分答案之后 根据二分的时间 可以确定每个塔的匹配数
二分图匹配要求每个点都是等价的 因此这道题只能用拆点来做
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int N=55;
const double eps=1e-9;
int read()
{
int x=0,f=0,c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return f?-x:x;
}
//二分图由于是认为的分成了两个集合 左右集合所以点的编号可以重复
struct Edge
{
int to,next;
}e[N*N*N];//No3: the number of left:n*n the number of right: n so we need n^3 edges
int head[N*N*2],cnt,num;
void add(int a,int b){ e[++cnt]=(Edge){b,head[a]};head[a]=cnt;}
double dis[N][N];
int X1[N],Y1[N],X2[N],Y2[N];
double getdis(int x,int y,int _x,int _y){return sqrt((x-_x)*(x-_x)+(y-_y)*(y-_y));}
int n,m,t2,v; double t1;
bool vis[N];
int match[N];
bool dfs(int x)
{
for(int i=head[x];i;i=e[i].next)
{
int y=e[i].to;
if(vis[y]) continue; vis[y]=1;
if(!match[y]|| dfs(match[y]) ){ match[y]=x; return true;}
}
return false;
}
//mid can be very large so we can not enumerate time
//upper bound: each defensive tower launch m missile
bool check(double mid)
{
memset(head,0,sizeof head); cnt=0; num=0;
memset(match,0,sizeof match);//No1: clear match array
for(int i=1;i<=n;i++)//enumerate each defensive tower
{
for(int j=1;j<=m;j++)//enumerate each missle
{
double t=(j-1)*(t1+t2)+t1;
if(t>mid) break;
bool flag=1;
for(int k=1;k<=m;k++)
if( (mid-t)*v>=dis[i][k])
{
if(flag) num++,flag=0;//No2: strict correspondence
add(num,k);
}
}
}
int ans=0;
for(int i=1;i<=num;i++)
{
memset(vis,0,sizeof vis);
ans+=dfs(i);
}
return ans>=m;
}
int main()
{
n=read();m=read();t1=read()*1.0/60;t2=read();v=read();
for(int i=1;i<=m;i++) X2[i]=read(),Y2[i]=read();
for(int i=1;i<=n;i++) X1[i]=read(),Y1[i]=read();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
dis[i][j]=getdis(X1[i],Y1[i],X2[j],Y2[j]);
double l=0,r=1e6;
while(r-l>eps)
{
double mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid;
}
printf("%.6lf",r);
}
注意:
1.二分图两边编号可以重复 但是只能加从左向右的单向边
2.eps要设置到1e-9才能够满足1e-6的精度要求
3. 边和点的空间一定要开的足够的大

浙公网安备 33010602011771号