zoj2589Circles(平面图的欧拉定理)
连通图中:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 55
#define LL long long
#define INF 0xfffffff
const double eps = 1e-;
const double pi = acos(-1.0);
const double inf = ~0u>>; struct point
{
double x,y;
point(double x=,double y=):x(x),y(y){}
};
vector<point>ed[N];
vector<int>dd[N];
vector<point>td[N];
struct circle
{
point c;
double r;
point ppoint(double a)
{
return point(c.x+cos(a)*r,c.y+sin(a)*r);
}
};
circle cp[N],cq[N];
int fa[N];
typedef point pointt;
pointt operator -(point a,point b)
{
return point(a.x-b.x,a.y-b.y);
} int dcmp(double x)
{
if(fabs(x)<eps) return ;
return x<?-:;
} bool operator == (const point &a,const point &b)
{
return dcmp(a.x-b.x)==&&dcmp(a.y-b.y)==;
}
double dis(point a)
{
return sqrt(a.x*a.x+a.y*a.y);
}
double angle(point a)//计算向量极角
{
return atan2(a.y,a.x);
}
double sqr(double x) { return x * x; } bool intersection(const point& o1, double r1, const point& o2, double r2,int k,int kk)
{
double d = dis(o1- o2);
if (d < fabs(r1 - r2) - eps || d > r1 + r2 + eps)
{
return false;
}
double cosa = (sqr(r1) + sqr(d) - sqr(r2)) / ( * r1 * d);
double sina = sqrt(max(., . - sqr(cosa)));
point p1 = o1,p2 = o1;
p1.x += r1 / d * ((o2.x - o1.x) * cosa + (o2.y - o1.y) * -sina);
p1.y += r1 / d * ((o2.x - o1.x) * sina + (o2.y - o1.y) * cosa);
p2.x += r1 / d * ((o2.x - o1.x) * cosa + (o2.y - o1.y) * sina);
p2.y += r1 / d * ((o2.x - o1.x) * -sina + (o2.y - o1.y) * cosa);
//cout<<p1.x<<" --"<<p2.x<<" "<<o1.x<<" "<<o1.y<<" "<<o2.x<<" "<<o2.y<<endl;
//printf("%.10f %.10f %.10f %.10f\n",p1.x,p1.y,p2.x,p2.y);
ed[k].push_back(p1);
ed[k].push_back(p2);
ed[kk].push_back(p1);
ed[kk].push_back(p2); return true;
}
bool cmp(circle a, circle b)
{
if(dcmp(a.r-b.r)==)
{
if(dcmp(a.c.x-b.c.x)==)
return a.c.y<b.c.y;
return a.c.x<b.c.x;
}
return a.r<b.r;
}
bool cmpp(point a,point b)
{
if(dcmp(a.x-b.x)==)
return a.y<b.y;
return a.x<b.x;
}
int find(int x)
{
if(fa[x]!=x)
{
fa[x] = find(fa[x]);
return fa[x];
}
return x;
}
int main()
{
int t,i,j,n;
cin>>t;
while(t--)
{
scanf("%d",&n);
for(i = ; i <= n ;i++)
{
ed[i].clear();fa[i] = i;
dd[i].clear();
td[i].clear();
}
for(i = ; i <= n ;i++)
scanf("%lf%lf%lf",&cp[i].c.x,&cp[i].c.y,&cp[i].r);
sort(cp+,cp+n+,cmp);
int g = ;
cq[g] = cp[g];
for(i = ; i <= n; i++)
{
if(cp[i].c==cp[i-].c&&dcmp(cp[i].r-cp[i-].r)==)
continue;
cq[++g] = cp[i];
}
for(i = ; i <= g; i++)
{
for(j = i+ ; j <= g; j++)
{
int flag = intersection(cq[i].c,cq[i].r,cq[j].c,cq[j].r,i,j);
if(flag == ) continue;
int tx = find(i),ty = find(j);
fa[tx] = ty;
}
}
for(i = ; i <= g; i++)
{
int fx = find(i);
dd[fx].push_back(i);
}
int B=,V=;
int ans = ;
int num = ;
for(i = ; i <= g; i++)
{
if(dd[i].size()==) continue;
B = ,V = ;
for(j = ;j < dd[i].size() ; j++)
{
int u = dd[i][j];
if(ed[u].size()==)
{
B++;
continue;
}
sort(ed[u].begin(),ed[u].end(),cmpp);
td[i].push_back(ed[u][]);
int o = ;
for(int e = ; e < ed[u].size() ; e++)
{
//printf("%.10f %.10f\n",ed[u][e].x,ed[u][e].y);
td[i].push_back(ed[u][e]);
if(ed[u][e]==ed[u][e-]) continue;
else o++;
}
B+=o;
}
sort(td[i].begin(),td[i].end(),cmpp);
V+=;
// cout<<td[i].size()<<endl;
for(j = ; j < td[i].size() ; j++)
{
//printf("%.10f %.10f\n",td[i][j].x,td[i][j].y);
if(td[i][j]==td[i][j-]) continue;
else V++; }
// cout<<B+1-V<<" "<<B<<" "<<V<<endl;
ans+=B+-V;
}
cout<<+ans<<endl;
}
return ;
}
zoj2589Circles(平面图的欧拉定理)的更多相关文章
- LA 3263 (平面图的欧拉定理) That Nice Euler Circuit
题意: 平面上有n个端点的一笔画,最后一个端点与第一个端点重合,即所给图案是闭合曲线.求这些线段将平面分成多少部分. 分析: 平面图中欧拉定理:设平面的顶点数.边数和面数分别为V.E和F.则 V+F- ...
- Codeforces 1392I - Kevin and Grid(平面图的欧拉定理+FFT)
Codeforces 题面传送门 & 洛谷题面传送门 模拟赛考到一道和这题有点类似的题就来补了 神仙 GLBR I %%%%%%%%%%%%%%%%%%%% 不过感觉见过类似的题目之后就比较套 ...
- poj2284 That Nice Euler Circuit(欧拉公式)
题目链接:poj2284 That Nice Euler Circuit 欧拉公式:如果G是一个阶为n,边数为m且含有r个区域的连通平面图,则有恒等式:n-m+r=2. 欧拉公式的推广: 对于具有k( ...
- ACM计算几何题目推荐
//第一期 计算几何题的特点与做题要领: 1.大部分不会很难,少部分题目思路很巧妙 2.做计算几何题目,模板很重要,模板必须高度可靠. 3.要注意代码的组织,因为计算几何的题目很容易上两百行代码,里面 ...
- [bzoj1997][Hnoi2010]Planar(2-sat||括号序列)
开始填连通分量的大坑了= = 然后平面图有个性质m<=3*n-6..... 由平面图的欧拉定理n-m+r=2(r为平面图的面的个数),在极大平面图的情况可以代入得到m=3*n-6. 网上的证明( ...
- ●POJ 2284 That Nice Euler Circuit
题链: http://poj.org/problem?id=2284 题解: 计算几何,平面图的欧拉定理 欧拉定理:设平面图的定点数为v,边数为e,面数为f,则有 v+f-e=2 即 f=e-v+2 ...
- NOIP2018 No regrets youth
NOIP2018在即,20181009总结一些易错的知识点和解题方法 ——by ljc20020730 HGOI NOIP2018 No regrets youth ! NOIP2018 No reg ...
- poj 2284 That Nice Euler Circuit 解题报告
That Nice Euler Circuit Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 1975 Accepted ...
- LA_3263_That_Nice_Euler_Circuits_(欧拉定理+计算几何基础)
描述 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=15& ...
随机推荐
- Windows 7 驱动开发
本文是对Win7(64)+VS2010+WDK7.1.0(WinDDK\7600.16385.1)开发驱动的小结. 一.系统工具 1.Win7(amd64位)系统 注:已装系统后,管理员身份运行cmd ...
- Maven invalid task...
执行maven构建项目报错: Invalid task '‐DgroupId=*': you must specify a valid lifecycle phase, or a goal in th ...
- 64位系统安装ODBC驱动的方法
为了更充分的利用硬件资源,我想很多人都开使用64位操作系统了,同时你可以也发现了在64位操作系统上ODBC的驱动找不到了,所以ODBC的东西都没法用了. 因为2007以前版本的Office只有32位版 ...
- ZOJ 3860: - Find the Spy
3860 - Find the Spy Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%lld & %llu S ...
- YTU 2986: 删除区间内的元素(线性表)
2986: 删除区间内的元素(线性表) 时间限制: 1 Sec 内存限制: 2 MB 提交: 8 解决: 3 题目描述 若一个线性表L采用顺序存储结构,其中元素都为整数.设计一个算法,删除元素值在 ...
- 类型解释器——C专家编程读书笔记
对于声明,应该按下面的步骤来进行解释: 1) 声明从它的名字开始读取,然后按照优先级顺序依次读取 2) 优先级顺序 a) 括号括起来的部分 b) 后缀操作符,()表示函数,[]表示数组 c) 前缀操作 ...
- Java fundamentals of basic IO
IO is a problem difficult to handle in various of systems because it always becomes a bottleneck in ...
- 万年历---java版
程序难点 : 1. 每年每个月有多少天? 2. 每个月的1号是星期几? 3. 每年的2月份是多少天? 难点解析 : 1. 每年每个月除去1 3 5 7 8 10 12是31天以外, 其他月份(除去2月 ...
- java-cmd-命令行编译和运行java文件
一.使用的工具 1.javac 2.java 二.命令 项目目录只这样的 D:/project/src/com/example/Child.java D:/project/src/com/exampl ...
- java网页抓取
网页抓取就是,我们想要从别人的网站上得到我们想要的,也算是窃取了,有的网站就对这个网页抓取就做了限制,比如百度 直接进入正题 //要抓取的网页地址 String urlStr = "http ...