zoj2318 getout(计算几何)
来源:互联网 发布:手机dj软件 编辑:程序博客网 时间:2024/06/16 15:32
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1318
题意:
你是一个圆,二维坐标中有很多其他n个圆,给出n个圆心及半径,再给你自己的圆心及半径,问这个圆能不能逃出这n个圆的包围。
tip:
好神奇的题。。首先考虑把自己这个圆变成点,把别的圆的半径加上自己这个半径就好了。如果某两个圆相交或相切,那么他们组成的封闭区间可以用连接其两圆心的线段表示,这样能得到若干线段,于是问题变成,若干线段中,是否能组成一个封闭区域,且起始圆心在其内。
按顺时针扫描每一条边,如果点在里面,点与所有线段两个端点角度和为2π,如果逆时针来,就是-2π。 如果在多边形外的话,和必然是0,于是加边i j 边权为从起始圆心到I和到j的角度和(正负各加一条),如果整个图有负环,就相当于找到一个-2π,说明出不去了,spfa即可。。
#include <cstdio>#include <iostream>#include <cstring>#include <queue>#include <cmath>#include <algorithm>using namespace std;const int maxn = 340;const double eps = 1e-8;int n,tot,head[maxn],num[maxn];bool inq[maxn];struct Tcircle{ double x,y,r;}p[maxn];double dis[maxn];struct node{ int u,v,next; double w;}edges[maxn*maxn];void add(int u,int v,double w){ edges[tot].v = v;edges[tot].w = w;edges[tot].next = head[u];head[u] = tot++;}void init(){ tot = 0;memset(head,-1,sizeof(head)); scanf("%d",&n); for(int i = 1 ;i <= n ; i++){ scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r); } scanf("%lf%lf%lf",&p[0].x,&p[0].y,&p[0].r); for(int i = 1; i <= n ; i++) p[i].r += p[0].r;}double dist(int i,int j){ return sqrt( (p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y) );}bool spfa(){ queue<int>q; for(int i = 1;i <= n;i++){ q.push(i); inq[i] = true; num[i] = 0; dis[i] = 0.0; } while(!q.empty()){ int tmp = q.front();q.pop(); inq[tmp] = 0; for(int k = head[tmp];k != -1;k = edges[k].next){ if(dis[edges[k].v] > eps+dis[tmp]+edges[k].w){ dis[edges[k].v] = dis[tmp]+edges[k].w; if(!inq[edges[k].v]){ inq[edges[k].v] = true; q.push(edges[k].v); num[edges[k].v]++; if(num[edges[k].v] > n-1) return true; } } } } return false;}void sov(){ for(int i = 1; i <= n ; i++){ for(int j = i+1 ; j <= n ; j++){ if(p[i].r+p[j].r-dist(i,j) <= eps) continue; double ang = ( (p[i].x-p[0].x)*(p[j].x-p[0].x) + (p[i].y-p[0].y)*(p[j].y-p[0].y) )/dist(0,i)/dist(0,j); ang = acos(ang); if( (p[i].x-p[0].x) *(p[j].y-p[0].y) - (p[j].x-p[0].x) * (p[i].y-p[0].y) >= 0){ add(i,j,ang);add(j,i,-ang); } else{ add(i,j,-ang);add(j,i,ang); } } }}int main(){ int T; scanf("%d",&T); while(T--){ init(); sov(); if(spfa()) printf("NO\n"); else printf("YES\n"); if(T) printf("\n"); }}
阅读全文
0 0
- zoj2318 getout(计算几何)
- POJ2318(计算几何)
- poj1939(计算几何)
- POJ1265Area(计算几何)
- sicily_1012 (计算几何)
- HDU1086(计算几何)
- Intersection (计算几何)
- 计算几何(一)
- 计算几何(草稿)
- 计算几何 - 二维几何基础 (模板)
- poj3304Segments+计算几何(二维几何模板)
- 计算几何-常用几何函数(模板)
- 计算几何总结(一)
- 计算几何总结(二)
- POJ1113Wall(计算几何基础)
- hdu 2876 (计算几何)
- 计算几何模板(白皮书)
- 计算几何模板(依然)
- Linux下安装Mysql(yum指令)
- Python实现设计模式--07.原型模式(Prototype Pattern)
- CSS总结——2
- 【HTML5学习笔记】28:CSS3文本效果
- js获取本月开始时间和结束时间
- zoj2318 getout(计算几何)
- HTTP协议下GET与POST的区别
- Leetcode 287. Find the Duplicate Number
- 分布式数据库架构及企业实践--基于Mycat中间件pdf
- MySQL袖珍参考手册(第2版)pdf
- XML入门指南pdf
- XML原理及应用pdf
- DB2 SQL性能调优秘笈pdf
- DB2安装手册pdf