【NOIP2013模拟】导弹防御塔
2016-03-19 13:38
501 查看
Description
Freda的城堡——“Freda,城堡外发现了一些入侵者!”
“喵…刚刚探究完了城堡建设的方案数,我要歇一会儿嘛lala~”
“可是入侵者已经接近城堡了呀!”
“别担心,rainbow,你看呢,这是我刚设计的导弹防御系统的说~”
“喂…别卖萌啊……”
Freda控制着N座可以发射导弹的防御塔。每座塔都有足够数量的导弹,但是每座塔每次只能发射一枚。在发射导弹时,导弹需要T1秒才能从防御塔中射出,而在发射导弹后,发射这枚导弹的防御塔需要T2分钟来冷却。
所有导弹都有相同的匀速飞行速度V,并且会沿着距离最短的路径去打击目标。计算防御塔到目标的距离Distance时,你只需要计算水平距离,而忽略导弹飞行的高度。导弹在空中飞行的时间就是 (Distance/V) 分钟,导弹到达目标后可以立即将它击毁。
现在,给出N座导弹防御塔的坐标,M个入侵者的坐标,T1、T2和V,你需要求出至少要多少分钟才能击退所有的入侵者。
Solution
讲解一下
首先,多个炮塔的导弹是可以同时发的,那么这道题就水很多了。首先,考虑有发炮时间和冷却时间,对一个炮塔可以瞄准多个目标,多个目标瞄准后时间是连续的,所以可以接连不断地发炮。
用什么
发现是有两组点,长得那么像二分图啊。但是是求最小的分钟数,最大最小,二分!怎么做
其实这是一个很经典的模型,一个图,求在一个过程之后的最大最小值,二分后,在判断是否可行。因为可以发多个导弹,所以一个炮塔可以连出m条边,表示发m个炮。然后在连边的时候判断,这条边用的时间是否满足限制,否则不连边。
这道题好坑
输入的是n,m但是下面的是以m,n的顺序输入的。
死白的是。
Code
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define fo(i,a,b) for(i=a;i<=b;i++) using namespace std; const int maxn=500000; const int maxx=500000; int i,j,t,n,m,ans,v,k; double l,r,mid,dis[maxx],o,t1,t2; int first[maxx],next[maxx],last[maxx],num,fan[maxn],d[maxx]; int x[maxn],y[maxn],xx[maxn],yy[maxn],tot; int chang[maxx]; void add(int x,int y,double z){ last[++num]=y; next[num]=first[x]; first[x]=num; chang[num]=z; fan[num]=num+1; last[++num]=x; next[num]=first[y]; first[y]=num; chang[num]=0; fan[num]=num-1; } double dian(int x,int y,int xx,int yy){ return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy)); } bool bfs(){ int i,j,k; i=0;j=1;memset(dis,0,sizeof(dis));dis[0]=1;d[1]=0; while(i<j){ k=first[d[++i]]; while(k!=0){ if(dis[last[k]]==0&&chang[k]>0){ dis[last[k]]=dis[d[i]]+1; d[++j]=last[k]; } k=next[k]; } } return (dis[n*m+m+1]!=0); } int dinic(int x,int y){ int i,j,t,p; if (x==n*m+m+1){ return y; } j=first[x]; p=0; while(j!=0){ i=last[j]; if (chang[j]>0&&dis[i]==dis[x]+1){ t=dinic(i,min(y,chang[j])); if (t>0) { chang[j]-=t; chang[fan[j]]+=t; y-=t;p+=t;if (y==0) break; } } j=next[j]; } if (p==0) dis[x]=-1; return p; } bool pan(int x){ int t=0; ans=0; while(bfs()){ t=dinic(0,0x7fffffff); ans+=t; } if(ans==m)return 1;else return 0; } int main(){ scanf("%d%d%lf%lf%d",&n,&m,&t1,&t2,&v); fo(i,1,m){ scanf("%d%d",&x[i],&y[i]); } fo(i,1,n){ scanf("%d%d",&xx[i],&yy[i]); } l=0,r=100000; while(r-l>1e-7){ mid=(l+r)/2; memset(first,0,sizeof(first)); num=0; fo(i,1,n) fo(j,1,m) add(0,(i-1)*m+j,1); fo(i,1,n){ fo(j,1,m){ fo(k,1,m){ o=dian(xx[i],yy[i],x[k],y[k])/v+t1*j/60+t2*(j-1); if(o>mid)continue; add((i-1)*m+j,n*m+k,1); } } } fo(i,1,m)add(n*m+i,n*m+m+1,1); if(pan(mid))r=mid;else l=mid; } printf("%.6lf\n",l); }
相关文章推荐
- 软件工程课程作业(三)--四则运算3(C++)
- 四则运算3+psp0
- Spark配置文件详解
- 多表数据记录查询
- POJ 1860 Currency Exchange (SPFA松弛)
- CodeForces 596A
- JS的魅力
- 【转】Fiddler的基本介绍
- TFS 10周年生日快乐 – TFS与布莱恩大叔的故事
- java.util.Stack类中的peek()方法
- 四则运算终结版
- codeforces 655C C. Enduring Exodus(二分)
- 给button添加点击事件,打开一个新的窗体
- make警告:检测到时钟错误
- Delphi常见图象格式转换技术
- java编程思想-字符串
- IOS CALayer(一)
- 计算机网络_面试
- MySQL 新增库同步到Slave
- 【java算法】约瑟夫问题求解