【bzoj1822】[JSOI2010]Frozen Nova 冷冻波 计算几何+二分+网络流最大流
题目描述
WJJ喜欢“魔兽争霸”这个游戏。在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀死一个小精灵。我们认为,巫妖和小精灵都可以看成是平面上的点。 当巫妖和小精灵之间的直线距离不超过R,且巫妖看到小精灵的视线没有被树木阻挡(也就是说,巫妖和小精灵的连线与任何树木都没有公共点)的话,巫妖就可以瞬间杀灭一个小精灵。 在森林里有N个巫妖,每个巫妖释放Frozen Nova之后,都需要等待一段时间,才能再次施放。不同的巫妖有不同的等待时间和施法范围,但相同的是,每次施放都可以杀死一个小精灵。 现在巫妖的头目想知道,若从0时刻开始计算,至少需要花费多少时间,可以杀死所有的小精灵?
输入
输入文件第一行包含三个整数N、M、K(N,M,K<=200),分别代表巫妖的数量、小精灵的数量和树木的数量。 接下来N行,每行包含四个整数x, y, r, t,分别代表了每个巫妖的坐标、攻击范围和施法间隔(单位为秒)。 再接下来M行,每行两个整数x, y,分别代表了每个小精灵的坐标。 再接下来K行,每行三个整数x, y, r,分别代表了每个树木的坐标。 输入数据中所有坐标范围绝对值不超过10000,半径和施法间隔不超过20000。
输出
输出一行,为消灭所有小精灵的最短时间(以秒计算)。如果永远无法消灭所有的小精灵,则输出-1。
样例输入
2 3 1
-100 0 100 3
100 0 100 5
-100 -10
100 10
110 11
5 5 10
样例输出
5
题解
计算几何+二分+网络流最大流
首先要解决的是是否能够攻击到,如果两个点形成的线段与所有圆都没有公共点,那么就可以攻击到。
线段与圆有公共点,需要满足两个条件之一:(1)线段某端点在圆内 (2)直线与圆有公共点,且以线段和端点与圆心连线的夹角是锐角。
其中直线与圆有公共点可以使用点到直线距离公式:$\frac{|ax_0+by_0+c|}{\sqrt{a^2+b^2}}$,夹角是锐角可以使用余弦定理的推论:如果$a^2<b^2+c^2$,那么$A$是锐角。
判断完以后就是经典的二分+最大流判断问题了:二分时间,S向巫妖连边,容量为mid时间攻击次数;巫妖向能够攻击到的小精灵连边,容量为1;小精灵向T连边,容量为1。如果满流则mid可行,否则不可行。
注意攻击次数的计算公式:$\lfloor\frac{mid}t\rfloor+1$,即开场是没有冷却的。(为这个问题纠结了半天= =)
#include <queue>
#include <cstdio>
#include <cstring>
#define N 410
#define M 200010
using namespace std;
typedef long long ll;
queue<int> q;
ll xn[N] , yn[N] , rn[N] , tn[N] , xm[N] , ym[N] , xk[N] , yk[N] , rk[N];
int n , m , k , v[N][N] , head[N] , to[M] , val[M] , next[M] , cnt , s , t , dis[N];
inline ll squ(ll x)
{
return x * x;
}
bool connect(int a , int b)
{
if(squ(xn[a] - xm[b]) + squ(yn[a] - ym[b]) > squ(rn[a])) return 0;
int i;
for(i = 1 ; i <= k ; i ++ )
if(squ(xn[a] - xk[i]) + squ(yn[a] - yk[i]) <= squ(rk[i]) || squ(xm[b] - xk[i]) + squ(ym[b] - yk[i]) <= squ(rk[i]) || (
squ(yn[a] * (xk[i] - xm[b]) - ym[b] * (xk[i] - xn[a]) - yk[i] * (xn[a] - xm[b])) <= squ(rk[i]) * (squ(xn[a] - xm[b]) + squ(yn[a] - ym[b])) &&
squ(xn[a] - xm[b]) + squ(yn[a] - ym[b]) + squ(xn[a] - xk[i]) + squ(yn[a] - yk[i]) >= squ(xm[b] - xk[i]) + squ(ym[b] - yk[i]) &&
squ(xn[a] - xm[b]) + squ(yn[a] - ym[b]) + squ(xm[b] - xk[i]) + squ(ym[b] - yk[i]) >= squ(xn[a] - xk[i]) + squ(yn[a] - yk[i])))
return 0;
return 1;
}
void add(int x , int y , int z)
{
to[++cnt] = y , val[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
to[++cnt] = x , val[cnt] = 0 , next[cnt] = head[y] , head[y] = cnt;
}
bool bfs()
{
int x , i;
memset(dis , 0 , sizeof(dis));
while(!q.empty()) q.pop();
dis[s] = 1 , q.push(s);
while(!q.empty())
{
x = q.front() , q.pop();
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && !dis[to[i]])
{
dis[to[i]] = dis[x] + 1;
if(to[i] == t) return 1;
q.push(to[i]);
}
}
}
return 0;
}
int dinic(int x , int low)
{
if(x == t) return low;
int temp = low , i , k;
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && dis[to[i]] == dis[x] + 1)
{
k = dinic(to[i] , min(temp , val[i]));
if(!k) dis[to[i]] = 0;
val[i] -= k , val[i ^ 1] += k;
if(!(temp -= k)) break;
}
}
return low - temp;
}
bool judge(int mid)
{
int i , j , sum = 0;
memset(head , 0 , sizeof(head)) , cnt = 1;
for(i = 1 ; i <= n ; i ++ ) add(s , i , mid / tn[i] + 1);
for(i = 1 ; i <= m ; i ++ ) add(i + n , t , 1);
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= m ; j ++ )
if(v[i][j])
add(i , j + n , 1);
while(bfs()) sum += dinic(s , 1 << 30);
return sum == m;
}
int main()
{
int i , j , l = 0 , r = 2000000 , mid , ans = -1;
scanf("%d%d%d" , &n , &m , &k) , s = 0 , t = n + m + 1;
for(i = 1 ; i <= n ; i ++ ) scanf("%lld%lld%lld%lld" , &xn[i] , &yn[i] , &rn[i] , &tn[i]);
for(i = 1 ; i <= m ; i ++ ) scanf("%lld%lld" , &xm[i] , &ym[i]);
for(i = 1 ; i <= k ; i ++ ) scanf("%lld%lld%lld" , &xk[i] , &yk[i] , &rk[i]);
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= m ; j ++ )
v[i][j] = connect(i , j);
while(l <= r)
{
mid = (l + r) >> 1;
if(judge(mid)) ans = mid , r = mid - 1;
else l = mid + 1;
}
printf("%d\n" , ans);
return 0;
}
【bzoj1822】[JSOI2010]Frozen Nova 冷冻波 计算几何+二分+网络流最大流的更多相关文章
- 【BZOJ1822】[JSOI2010]Frozen Nova 冷冻波 几何+二分+网络流
[BZOJ1822][JSOI2010]Frozen Nova 冷冻波 Description WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀 ...
- Bzoj1822 [JSOI2010]Frozen Nova 冷冻波
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1933 Solved: 608 Description WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖 ...
- bzoj1822: [JSOI2010]Frozen Nova 冷冻波网络流
思路比较显然:二分答案,流流流 但是实现的时候感觉自己数学捉急.. 一开始算了个直线到点距离.... 应该是线段到点距离 #include <bits/stdc++.h> #define ...
- 【计算几何】【二分答案】【最大流】bzoj1822 [JSOI2010]Frozen Nova 冷冻波
用三角形面积什么的算算点到直线的距离之类……其实相切的情况是可行的……剩下的就跟某SDOI2015一样了. #include<cstdio> #include<cmath> # ...
- BZOJ1822 [JSOI2010]Frozen Nova 冷冻波 二分+最大流
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1822 题解 好久没做网络流的,都没有想到网络流... 首先暴力判断一下一个巫妖和一个精灵之间能 ...
- 1822: [JSOI2010]Frozen Nova 冷冻波 二分最大流
1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 585 Solved: 175[Subm ...
- BZOJ 1822[JSOI2010]Frozen Nova 冷冻波
网络流+二分. n^3枚举判断每个巫妖可以攻击的精灵,向其连1的边,每个精灵向汇点连1的边. 二分答案,修改源点流向每个巫妖的cap,跑最大流看是否等于精灵数. 恩,看起来没什么毛病. 然后狂WA不止 ...
- BZOJ-1822 Frozen Nova 冷冻波 计(jie)算(xi)几何+二分+最大流判定+经典建图
这道逼题!感受到了数学对我的深深恶意(#‵′).... 1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec Memory Limit: 64 MB S ...
- BZOJ1822 Frozen Nova 冷冻波
1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec Memory Limit: 64 MB Description WJJ喜欢“魔兽争霸”这个游戏. ...
随机推荐
- Exceptions and Errors on iOS
异常:程序缺陷导致:不可恢复:给开发者使用: 错误:资源受限导致:可恢复:提示给用户. https://blog.jayway.com/2010/10/13/exceptions-and-errors ...
- 2018.5.14 XML文档类型定义----DTD
1.DTD概述 一个完全意义上的XML文件不仅仅是Well-fromed(格式良好的),而且还应该是使用了一些自定义的标记ValidatingXMl(有效的)文档也就是说他必须遵守文档类型的定义中已声 ...
- 回归树的原理及Python实现
大名鼎鼎的 GBDT 算法就是用回归树组合而成的.本文就回归树的基本原理进行讲解,并手把手.肩并肩地带您实现这一算法. 1. 原理篇 1.1 最简单的模型 如果预测某个连续变量的大小,最简单的模型之一 ...
- edge不能上网-代码 INET_E_RESOURCE_NOT_FOUND
这个问题 ,网上有很多解决方法,我基本都测试了一遍,可是我都没有用 情况:首先,我开始的时候是可以用的,然后在公司,开了代理,就不能使用了,这是我之后多次尝试发现的,所以你也遇到和我一样的情况不必惊慌 ...
- require.js模块化开发
模块化开发的原因: 1.引入的js过多然后在加载的过程中容易出现假死的状态,导致页面会发生白屏 2.变量名的问题 在多人协作开发的时候容易出现变量名的冲突 面向对象 3.引入优先级的问题 模块化开发分 ...
- WebService简单入门
写在前面的话: 当两个人碰面后,产生了好感,如果需要得到双方的信息,那么双方的交流是必不可少的!应用程序也如此, 各个应用程序之间的交流就需要WebService来作为相互交流的桥梁! 项目目的: 程 ...
- linux替换yum源及配置本地源
linux系统安装后自带的bash源由于在国外,安装软件包的时候会非常慢,最好替换一下yum源. 关于yum源的简单介绍 yum的主要功能是更方便地添加,删除和更新rpmba ...
- 2D和3D效果
<style type="text/css"> #div1{ width: 200px; height: 200px; background-color:#aaa; c ...
- Volatile小结
1)Java 中能创建 Volatile 数组吗? 能,Java 中可以创建 volatile 类型数组,不过只是一个指向数组的引用,而不是整个数组.我的意思是,如果改变引用指向的数组,将会受到 vo ...
- Maya材质
mental ray--Indirect Lighting(物理学太阳天空) Final Gathering最终聚集 改变质量为production的,FG就是关闭需要重新打开 平行光, ...