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. mysql 函数示例(转)

    MySQL函数大全及用法示例 1.字符串函数ascii(str)   返回字符串str的第一个字符的ascii值(str是空串时返回0)  mysql> select ascii('2');   ...

  2. mysql实现消息队列

    mysql之消息队列   消息队列:在消息的传输过程中保存消息的容器. 消息队列管理器在将消息从它的源中继到它的目标时充当中间人.队列的主要目的是提供路由并保证消息的传递:如果发送消息时接收者不可用, ...

  3. 用ul li实现边框重合并附带鼠标经过效果

    边框重合这个效果并不难,只是我们没有真正的动手做过而已,下面让我们来谈谈用ul li如何实现边框重合,并附带鼠标经过效果 <!DOCTYPE html> <html lang=&qu ...

  4. Django 2.0 学习(19):Django 分页器

    Django 分页器 要使用Django实现分页功能,必须从Django中导入Paginator模块(painator - 分页器) views.py from django.shortcuts im ...

  5. https和http/2

    http://geek.csdn.net/news/detail/188003 HTTPS协议原理分析 HTTPS协议需要解决的问题 HTTPS作为安全协议而诞生,那么就不得不面对以下两大安全问题: ...

  6. Java线程Dump分析工具--jstack

    jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使 ...

  7. Valid Parentheses - LeetCode

    目录 题目链接 注意点 解法 小结 题目链接 Valid Parentheses - LeetCode 注意点 考虑输入为空的情况 解法 解法一:如果是'('.'{'.'['这三者就入栈,否则就判断栈 ...

  8. BZOJ4919 [Lydsy1706月赛]大根堆 【dp + 启发式合并】

    题目链接 BZOJ4919 题解 链上的\(LIS\)维护一个数组\(f[i]\)表示长度为\(i\)的\(LIS\)最小的结尾大小 我们可以用\(multiset\)来维护这个数组,子树互不影响,启 ...

  9. Tcp协议三次握手四次挥手

    一.什么是TCP TCP(Transmission Control Protocol 传输控制协议)是一种面向连接(连接导向)的.可靠的. 基于IP的传输层协议.TCP在IP报文的协议号是6. 二.什 ...

  10. HDU--4607

    题目: Park Visit 原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4607 分析:求树的直径.所谓树的直径,指的是一棵树里任意两点之间的最远距 ...