bzoj1822: [JSOI2010]Frozen Nova 冷冻波
1822: [JSOI2010]Frozen Nova 冷冻波
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1640 Solved: 516
[Submit][Status][Discuss]
Description
WJJ喜欢“魔兽争霸”这个游戏。在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀死一个小精灵。我们认为,巫妖和小精灵都可以看成是平面上的点。 当巫妖和小精灵之间的直线距离不超过R,且巫妖看到小精灵的视线没有被树木阻挡(也就是说,巫妖和小精灵的连线与任何树木都没有公共点)的话,巫妖就可以瞬间杀灭一个小精灵。 在森林里有N个巫妖,每个巫妖释放Frozen Nova之后,都需要等待一段时间,才能再次施放。不同的巫妖有不同的等待时间和施法范围,但相同的是,每次施放都可以杀死一个小精灵。 现在巫妖的头目想知道,若从0时刻开始计算,至少需要花费多少时间,可以杀死所有的小精灵?
Input
输入文件第一行包含三个整数N、M、K(N,M,K<=200),分别代表巫妖的数量、小精灵的数量和树木的数量。 接下来N行,每行包含四个整数x, y, r, t,分别代表了每个巫妖的坐标、攻击范围和施法间隔(单位为秒)。 再接下来M行,每行两个整数x, y,分别代表了每个小精灵的坐标。 再接下来K行,每行三个整数x, y, r,分别代表了每个树木的坐标。 输入数据中所有坐标范围绝对值不超过10000,半径和施法间隔不超过20000。
Output
输出一行,为消灭所有小精灵的最短时间(以秒计算)。如果永远无法消灭所有的小精灵,则输出-1。
Sample Input
2 3 1
-100 0 100 3
100 0 100 5
-100 -10
100 10
110 11
5 5 10
-100 0 100 3
100 0 100 5
-100 -10
100 10
110 11
5 5 10
Sample Output
5
HINT
二分完用流判定...计算几何....
1 #include<bits/stdc++.h> 2 #define rep(i,l,r) for(int i=l;i<=r;++i) 3 using namespace std; 4 typedef double d; 5 const int N=102333,inf=1e8; 6 int head[N],tot=1,Dis[N],n,m,K,l,r,mid,ans,T; 7 struct Edge{ 8 int to,next,w; 9 }e[N]; 10 struct node{ 11 int x,y,t,r; 12 }a[N],b[N],c[N]; 13 inline node operator-(node a,node b){ 14 node t;t.x=a.x-b.x;t.y=a.y-b.y;return t; 15 } 16 inline d operator*(node a,node b){ 17 return a.x*b.y-a.y*b.x; 18 } 19 inline d dot(node a,node b){ 20 return a.x*b.x+a.y*b.y; 21 } 22 inline d dis(node a,node b){ 23 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 24 } 25 inline d dis(node a,node b,node p){ 26 if(dot(a-p,b-p)>0) 27 return min(dis(a,p),dis(b,p)); 28 return abs((p-a)*(b-a)/dis(a,b)); 29 } 30 bool pd(int x,int y){ 31 if(dis(a[x],b[y])>a[x].r)return 0; 32 rep(i,1,K)if(dis(a[x],b[y],c[i])<c[i].r)return 0; 33 return 1; 34 } 35 inline bool bfs(){ 36 for(int i=0;i<=T;i++) Dis[i]=-1; queue<int>q; q.push(0); Dis[0]=0; 37 while(!q.empty()) { 38 int x=q.front(); q.pop(); 39 for(int k=head[x];k;k=e[k].next) 40 if(Dis[e[k].to]<0 && e[k].w>0) { 41 Dis[e[k].to]=Dis[x]+1; q.push(e[k].to); 42 } 43 } 44 if(Dis[T]>0) return 1;else return 0; 45 } 46 int find(int x,int low){ 47 if(x==T) return low; 48 int delta=low,now; 49 for(int k=head[x];k;k=e[k].next) 50 if(e[k].w>0 && Dis[e[k].to]==Dis[x]+1){ 51 now=find(e[k].to,min(e[k].w,delta)); 52 e[k].w-=now; e[k^1].w+=now; delta-=now; 53 if(!delta) return low; 54 } 55 Dis[x]=-1; 56 return low-delta; 57 } 58 inline void ins(int u,int v,int w) { 59 e[++tot].to=v; e[tot].next=head[u]; head[u]=tot; e[tot].w=w; 60 } 61 inline void insert(int u,int v,int w) { 62 ins(u,v,w); ins(v,u,0); 63 } 64 inline bool run(int x){ 65 memset(head,0,sizeof head); tot=1; 66 rep(i,1,n) insert(0,i,x/a[i].t+1); 67 rep(i,1,n) rep(j,1,m) if(pd(i,j))insert(i,j+n,1); 68 rep(i,1,m) insert(i+n,T,1); 69 int sum=0; 70 while(bfs())sum+=find(0,inf); 71 return sum==m; 72 } 73 int main(){ 74 scanf("%d%d%d",&n,&m,&K); 75 rep(i,1,n) scanf("%d%d%d%d",&a[i].x,&a[i].y,&a[i].r,&a[i].t); 76 rep(i,1,m) scanf("%d%d",&b[i].x,&b[i].y); 77 rep(i,1,K) scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].r); 78 ans=-1; r=20000*200; T=1+n+m; 79 while(l<=r){ 80 int mid=l+r>>1; 81 if(run(mid)) ans=mid,r=mid-1;else l=mid+1; 82 } 83 printf("%d\n",ans); 84 }