这道逼题!感受到了数学对我的深深恶意(#‵′)。。。。

1822: [JSOI2010]Frozen Nova 冷冻波

Time Limit: 10 Sec Memory Limit: 64 MB

Submit: 1282 Solved: 382

[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

Sample Output

5

HINT

Source

JSOI2010第二轮Contest1

巫(污)妖!

这道题啊,污!

建图:

超级源向所有巫妖建图,边权为time/nova【i】.t+1(二分出来的总时间,除去这个巫妖的施法冷却+1(0s可以释放第一个波))

每个巫妖和它所能打到得小精灵连边,边权为1

所有小精灵与超级汇连边,边权为1(因为每个小精灵只能被杀死1次)

然后二分(left=0,right=maxtime*m冷却最长的巫妖独自杀死所有小精灵的时间一定是最大的)总时间,建图,跑最大流判定即可

下面是计算(此处采用解析几何,因为人傻)几何部分关于判定巫妖是否能打到小精灵的判定:

巫妖有攻击半径r,所以能打到这个小精灵的要求起码,这个巫妖和这个精灵之间的距离要<=这个巫妖的施法半径:

平面间两点距离公式:

满足上述条件后还需要满足不被树挡住才能攻击到(在树中会失去视野。。。这个故事提示我们要带眼)

那么这个时候思考到,我们已知两点的坐标,树的坐标和树的半径

那么只要满足树的这个圆与这两点连成的直线没有交点即可。如果点到线段的最短距离都大于半径那一定不会相交。

于是转化成求点到线段的最短距离。

值得注意的是,这里是点到线段的最短距离,而非直线,所以不能直接套公式,应该理性的分类思考一下:

1.点的投影正好落在线段上,此时最短距离为这个垂线段的长度,求法与点到直线距离一样。

2.点的投影在线段的延长线上,这时最短距离为这个点到线段两端点的长度中较短的那条,由第一个条件公式得到即可。

那么如何判断点的投影是否在线段上呢?

这里采用的是,先用两点距离公式算出树、巫妖、小精灵三个点组成的三角形的三边长度,然后利用海伦公式求出面积S

海伦公式及推导:

然后在用点到直线距离公式求出,树这个点到这个线段所在直线的距离(垂线段)

点到直线的距离公式:

然后用树到两个端点中较大的那个端点为斜边,勾股出这个点在直线上的投影点到那个端点的距离,判断这个距离和线段的长度,如果线段长度长,则这个点在线段上return 点到直线的距离,否则return点到两个端点的距离中较小的那个距离

判断如果不被挡住,则可以攻击到,建图完成上述操作即可

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define M 1000010
int dis[M];
int q[M],h,t;
struct data{
int next,to,v;
}edge[M];
int head[M],cnt=1;
struct data1{
int x,y,r,t;
}nova[300];
struct data2{
int x,y;
}fairy[300];
struct data3{
int x,y,r;
}tree[300];
int n,m,k;
int maxt=0; void add(int u,int v,int w)
{
cnt++;
edge[cnt].next=head[u];
head[u]=cnt;
edge[cnt].to=v;
edge[cnt].v=w;
} double min(double x,double y)
{
if (x>y) return y;
else return x;
} double max(double x,double y)
{
if (x>y) return x;
else return y;
} double dist(int x1,int y1,int x2,int y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}//两点之间的距离 double Helen(double a,double b,double c)
{
double q=(a+b+c)/2;
return sqrt(q*(q-a)*(q-b)*(q-c));
}//海伦公式求面积 double gg(double x,double y)
{
return sqrt(x*x-y*y);
}//勾股定理 double mindis(int x1,int y1,int x2,int y2,int x3,int y3)
{
double d1=(fabs((y2-y1)*x3+(x1-x2)*y3+(x2*y1)-(x1*y2)))/(sqrt((y2-y1)*(y2-y1)+(x1-x2)*(x1-x2)));
double d2=dist(x1,y1,x3,y3);
double d3=dist(x2,y2,x3,y3);
double s=Helen(d2,d3,dist(x1,y1,x2,y2));
double x=gg(max(d2,d3),d1);
if (x>dist(x1,y1,x2,y2))
return min(d2,d3);
else
return d1;
}//点到线段的最短距离(树的圆心 到 巫妖和小精灵组成的线段 的距离)
//(x1,x2)表示巫妖的坐标,(x2,y2)表示小精灵的坐标,(x3,y3)表示树的坐标 void init()
{
scanf("%d%d%d",&n,&m,&k);
for (int i=1; i<=n; i++)
{
scanf("%d%d%d%d",&nova[i].x,&nova[i].y,&nova[i].r,&nova[i].t);
maxt=max(maxt,nova[i].t);
}
for (int i=1; i<=m; i++)
scanf("%d%d",&fairy[i].x,&fairy[i].y);
for (int i=1; i<=k; i++)
scanf("%d%d%d",&tree[i].x,&tree[i].y,&tree[i].r);
} void make(int ans)
{
//只要一个巫妖和一个小精灵之间的距离小于等于巫妖的施法范围 &&
//周围的树到这个线段的最短距离大于树的半径 就可以打到
//超级源点记为0,超级汇记为N+M+1,巫妖的编号从1~N,小精灵从N+1~N+M
cnt=1;memset(head,0,sizeof(head));
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
if (dist(nova[i].x,nova[i].y,fairy[j].x,fairy[j].y)<=1.0*nova[i].r)
{
bool f=true;
for (int l=1; l<=k; l++)
if (mindis(nova[i].x,nova[i].y,fairy[j].x,fairy[j].y,tree[l].x,tree[l].y)<=1.0*tree[l].r)
{
f=false;
break;
}
if (f==false)
continue;
add(i,n+j,1); add(n+j,i,0);
}
for (int i=1; i<=n; i++)
{
add(0,i,ans/nova[i].t+1);
add(i,0,0);
}
for (int j=1; j<=m; j++)
{
add(n+j,n+m+1,1);
add(n+m+1,n+j,0);
}
} bool bfs()
{
memset(dis,-1,sizeof(dis));
q[1]=0; dis[0]=1;
h=0; t=1;
while (h<t)
{
int j=q[++h],i=head[j];
while (i)
{
if (dis[edge[i].to]<0 && edge[i].v>0)
{
dis[edge[i].to]=dis[j]+1;
q[++t]=edge[i].to;
}
i=edge[i].next;
}
}
if (dis[n+m+1]>0)
return true;
else
return false;
} int dfs(int loc,int low)
{
int flow=0;
if (loc==n+m+1) return low;
int i=head[loc];
while (i)
{
if (edge[i].v>0 && dis[edge[i].to]==dis[loc]+1 && (flow=dfs(edge[i].to,min(low,edge[i].v))))
{
edge[i].v-=flow;
edge[i^1].v+=flow;
return flow;
}
i=edge[i].next;
}
return 0;
} int main()
{
init();
int ans;
int answer=-1;
int left=0,right=maxt*m,mid;
while (left<=right)
{
mid=(left+right)>>1;
make(mid);
ans=0;
while (bfs())
{
int now=0;
while ((now=dfs(0,0x7fffffff)))
ans+=now;
}
if (ans==m)
{answer=mid; right=mid-1;}
else
left=mid+1;
}
printf("%d",answer);
return 0;
}

BZOJ-1822 Frozen Nova 冷冻波 计(jie)算(xi)几何+二分+最大流判定+经典建图的更多相关文章

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

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

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

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

  3. BZOJ1822 Frozen Nova 冷冻波

    1822: [JSOI2010]Frozen Nova 冷冻波 Time Limit: 10 Sec  Memory Limit: 64 MB Description WJJ喜欢“魔兽争霸”这个游戏. ...

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

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

  5. Bzoj1822 [JSOI2010]Frozen Nova 冷冻波

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

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

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

  7. BZOJ 1822[JSOI2010]Frozen Nova 冷冻波

    网络流+二分. n^3枚举判断每个巫妖可以攻击的精灵,向其连1的边,每个精灵向汇点连1的边. 二分答案,修改源点流向每个巫妖的cap,跑最大流看是否等于精灵数. 恩,看起来没什么毛病. 然后狂WA不止 ...

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

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

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

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

随机推荐

  1. MongoDB学习(二)Windows环境安装MongoDB

    MongoDB的官方下载站是http://www.mongodb.org/downloads,可以去上面下载最新的程序下来. 在下载页面可以看到,对操作系统支持很全面,OS X.Linux.Windo ...

  2. 原生js颗粒页换图效果

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  3. NET Office 组件Spire

    高效而稳定的企业级.NET Office 组件Spire   在项目开发中,尤其是企业的业务系统中,对文档的操作是非常多的,有时几乎给人一种错觉的是"这个系统似乎就是专门操作文档的" ...

  4. 二叉树的遍历(递归,迭代,Morris遍历)

    二叉树的遍历: 先序,中序,后序: 二叉树的遍历有三种常见的方法, 最简单的实现就是递归调用, 另外就是飞递归的迭代调用, 最后还有O(1)空间的morris遍历: 二叉树的结构定义: struct ...

  5. [原创]JavaScript继承详解

    原文链接:http://www.cnblogs.com/sanshi/archive/2009/07/08/1519036.html 面向对象与基于对象 几乎每个开发人员都有面向对象语言(比如C++. ...

  6. Asp.net设计模式笔记之二:应用程序分离与关注点分离

    本次笔记主要涉及的内容如下: 1.将智能UI(SmartUI)反模式重构成分层方式的示例代码 2.分层设计与传统的Asp.net WebForm模型(代码后植)相比具有的优势 3.逻辑分层概念以及分离 ...

  7. 即学即会 Java 程序设计基础视频教程(100课整)无水印版

    课程总共包含100个课时,总授课长达27多个小时,内容覆盖面广,从入门到精通,授课通俗易懂,分析问题独到精辟通过本套视频的学习,学员能够快速的掌握java编程语言,成为java高手. 课程目录:课时1 ...

  8. DLL函数中内存分配及释放的问题

    DLL函数中内存分配及释放的问题 最近一直在写DLL,遇到了一些比较难缠的问题,不过目前基本都解决了.主要是一些内存分配引起问题,既有大家经常遇到的现象也有特殊的 情况,这里总结一下,做为资料. 错误 ...

  9. Android Studio导入Eclipse项目和一些常见的问题

    Android Studio版本 Eclipse项目工程:一个主工程,一个Emojicon依赖库. 有两种方式导入Eclipse工程: 1.兼容Eclipse 2.全新的Android Gradle ...

  10. css渐变

    常这样去定义一个渐变的div: 渐变1:(双色) background: -moz-linear-gradient(top, #456d6c %, #32b66a %); %,#456d6c), co ...