1822: [JSOI2010]Frozen Nova 冷冻波

Time Limit: 10 Sec  Memory Limit: 64 MB

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

Sample Output

5

Source

JSOI2010第二轮Contest1


题解

网络流 + 二分答案 + 计算几何

计算几何用点积和叉积计算点到线段距离,二分所需时间,网络流验证是否可行

大水题,数据有点坑qwq

代码

 #include<bits/stdc++.h>
using namespace std;
template <class _T> inline void read(_T &_x) {
int _t; bool flag = false;
while ((_t = getchar()) != '-' && (_t < '' || _t > '')) ;
if (_t == '-') _t = getchar(), flag = true; _x = _t - '';
while ((_t = getchar()) >= '' && _t <= '') _x = _x * + _t - '';
if (flag) _x = -_x;
}
typedef long long LL;
const int maxn = ;
const int maxm = ;
const double eps = 1e-;
inline int sign(double val) {return val < -eps ? - : val > eps; }
struct Point {
double x, y;
Point (double a = , double b = ):x(a), y(b) {}
}A[maxn], B[maxn], C[maxn];
double rA[maxn], rC[maxn];
double dot(Point a, Point b, Point c) {
return (b.x - a.x) * (c.x - a.x) + (b.y - a.y) * (c.y - a.y);
}
double cross(Point a, Point b, Point c) {
return (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y);
}
double dist(Point a, Point b) {
return hypot(a.x - b.x, a.y - b.y);
}
double ldis(Point a, Point b, Point c) {
if (dot(c, a, b) > ) return min(dist(a, c), dist(b, c));
return fabs(cross(a, b, c) / dist(a, b));
}
bool check(Point a, Point b, Point c, int pc) {
double dis = dist(a, b), r = dot(a, b, c) / dis;
if (r < || r > dis) return true;
return sign(fabs(cross(a, b, c) / r) - rC[pc]) > ;
}
struct Edge {
int v, flow, nxt;
Edge () {}
Edge (int a, int b, int c):v(a), flow(b), nxt(c) {}
}e[maxm];
int n, m, k, t[maxn], sink;
int fir[maxn], tag[maxn], cur[maxn], ecnt;
bool can[maxn][maxn];
inline void addedge (int a, int b, int c) {
e[++ecnt] = Edge (b, c, fir[a]), fir[a] = ecnt;
e[++ecnt] = Edge (a, , fir[b]), fir[b] = ecnt;
}
inline bool bfs() {
memset(tag, , sizeof (int) * (sink + ));
queue<int> q; q.push(), tag[] = ;
while (!q.empty()) {
int now = q.front(); q.pop();
for (int u = fir[now]; u; u = e[u].nxt) {
if (e[u].flow && !tag[e[u].v]) {
tag[e[u].v] = tag[now] + ;
q.push(e[u].v);
}
}
}
return tag[sink] != ;
}
int dfs(int now, int flow) {
if (now == sink) return flow;
int usd = ;
for (int &u = cur[now]; u; u = e[u].nxt) {
if (e[u].flow && tag[e[u].v] > tag[now]) {
int ret = dfs(e[u].v, min(e[u].flow, flow - usd));
if (ret) {
e[u].flow -= ret;
e[u ^ ].flow += ret;
usd += ret;
if (usd == flow) return flow;
}
}
}
return usd;
}
inline int dinic() {
int flow = ;
while (bfs()) {
for (int i = ; i <= sink; ++i) cur[i] = fir[i];
flow += dfs(, m);
}
return flow;
}
bool check(int tim) {
memset(fir, , sizeof (int) * (sink + ));
ecnt = ;
for (int i = ; i <= n; ++i) {
addedge(, i, tim / t[i] + );
for (int j = ; j <= m; ++j) if (can[i][j]) {
addedge(i, n + j, );
}
}
for (int i = ; i <= m; ++i) addedge(n + i, sink, );
return dinic() >= m;
}
int main() {
//freopen(".in", "r", stdin);
//freopen(".out", "w", stdout);
read(n), read(m), read(k);
for (int i = ; i <= n; ++i) {
scanf("%lf%lf%lf%d", &A[i].x, &A[i].y, &rA[i], &t[i]);
}
for (int i = ; i <= m; ++i) {
scanf("%lf%lf", &B[i].x, &B[i].y);
}
for (int i = ; i <= k; ++i) {
scanf("%lf%lf%lf", &C[i].x, &C[i].y, &rC[i]);
}
for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
bool flag = true;
double dis = dist(A[i], B[j]);
if (dis > rA[i]) continue;
for (int x = ; x <= k; ++x) {
if (ldis(A[i], B[j], C[x]) < rC[x]) {
flag = false;
break;
}
}
if (flag) can[i][j] = true;
}
}
for (int i = ; i <= m; ++i) {
bool flag = false;
for (int j = ; j <= n; ++j) if (can[j][i]) {
flag = true; break;
}
if (!flag) {
puts("-1");
return ;
}
}
sink = n + m + ;
int l = , r = * m, mid;
while (l < r) {
if (check(mid = (l + r) >> )) r = mid;
else l = mid + ;
}
cout << l << endl;
return ;
}

BZOJ1822 Frozen Nova 冷冻波的更多相关文章

  1. BZOJ-1822 Frozen Nova 冷冻波 计(jie)算(xi)几何+二分+最大流判定+经典建图

    这道逼题!感受到了数学对我的深深恶意(#‵′).... 1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec Memory Limit: 64 MB S ...

  2. 【BZOJ1822】[JSOI2010]Frozen Nova 冷冻波 几何+二分+网络流

    [BZOJ1822][JSOI2010]Frozen Nova 冷冻波 Description WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀 ...

  3. 1822: [JSOI2010]Frozen Nova 冷冻波 二分最大流

    1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 585  Solved: 175[Subm ...

  4. Bzoj1822 [JSOI2010]Frozen Nova 冷冻波

    Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1933  Solved: 608 Description WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖 ...

  5. 【bzoj1822】[JSOI2010]Frozen Nova 冷冻波 计算几何+二分+网络流最大流

    题目描述 WJJ喜欢“魔兽争霸”这个游戏.在游戏中,巫妖是一种强大的英雄,它的技能Frozen Nova每次可以杀死一个小精灵.我们认为,巫妖和小精灵都可以看成是平面上的点. 当巫妖和小精灵之间的直线 ...

  6. BZOJ 1822 Frozen Nova 冷冻波(最大流)

    题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1822 题意:WJJ喜欢“魔兽争霸”这个游戏.在 游戏中,巫妖是一种强大的英雄,它的技能F ...

  7. 【计算几何】【二分答案】【最大流】bzoj1822 [JSOI2010]Frozen Nova 冷冻波

    用三角形面积什么的算算点到直线的距离之类……其实相切的情况是可行的……剩下的就跟某SDOI2015一样了. #include<cstdio> #include<cmath> # ...

  8. bzoj1822: [JSOI2010]Frozen Nova 冷冻波网络流

    思路比较显然:二分答案,流流流 但是实现的时候感觉自己数学捉急.. 一开始算了个直线到点距离.... 应该是线段到点距离 #include <bits/stdc++.h> #define ...

  9. BZOJ1822 [JSOI2010]Frozen Nova 冷冻波 二分+最大流

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1822 题解 好久没做网络流的,都没有想到网络流... 首先暴力判断一下一个巫妖和一个精灵之间能 ...

随机推荐

  1. es6 javascript对象方法Object.assign()

    es6 javascript对象方法Object.assign() 2016年12月01日 16:42:34 阅读数:38583 1  基本用法 Object.assign方法用于对象的合并,将源对象 ...

  2. XHTML和HTML、CSS 验证器

    XHTML 验证器和 CSS 验证器.需要这些工具去验证你的页面是否符合 XHTML 和 CSS 标准,并且可以使用它查出奇正错误的地方. XHTML 验证器 地址:http://validator. ...

  3. [细品java]ThreadLocal源码学习

    ThreadLocal是线程局部变量,其中保存了特定于该线程的值.每个线程都拥有一份独立的副本值,即每个线程修改变量值不影响其他线程该变量的副本值.这些特定于线程的值保存在Thread对象中,当线程终 ...

  4. Logrotate还有谁记得它??

    我发现很多人的服务器上都运行着一些诸如每天切分Nginx日志之类的CRON脚本,大家似乎遗忘了Logrotate,争相发明自己的轮子,这真是让人沮丧啊!就好比明明身边躺着现成的性感美女,大家却忙着自娱 ...

  5. Code Blocks中配置OpenGL

    使用的文件:我的CSDN资源共享 将glut.h文件放到MinGw\include\GL目录下面 将glut32.dll文件放到C:\windows\system32目录下面(如果是64位操作系统的话 ...

  6. redis压力测试工具-----redis-benchmark

    redis做压测可以用自带的redis-benchmark工具,使用简单 压测命令:redis-benchmark -h 127.0.0.1 -p 6379 -c 50 -n 10000 压测需要一段 ...

  7. ACdream1092

    题意是给出某个地鼠的出现位置以及出现时间,人有一个移动速度,求此人最多可以打多少个地鼠? 我们根据时间把所有的地鼠排序,如果两个地鼠之间的距离不超过时间只差与速度的乘积,那说明打完上一只地鼠还可以打到 ...

  8. springmvc+mybatis 处理图片(二):显示图片

    数据库及配置文件等参考:springmvc+mybatis 处理图片(一):上传图片思路:把图片二进制信息写入到HttpServletResponse 的outputStream输出流中来显示图片.一 ...

  9. 【刷题】BZOJ 3524 [Poi2014]Couriers

    Description 给一个长度为n的序列a.1≤a[i]≤n. m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0 ...

  10. python之插入排序

    插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2).是稳定的排序方法.插入算法把要排序的数组分成两部 ...