zoj2589Circles(平面图的欧拉定理)

链接

连通图中:

设一个平面图形的顶点数为n,划分区域数为r,一笔画笔数为也就是边数m,则有:

n+r-m=2

那么不算外面的那个大区域的话 就可以写为 n+r-m = 1

那么这个题就可以依次求出每个连通图的r = m-n+1 累加起来 最后加上最外面那个平面。

注意交点的去重,对于一个圆的边数其实就是交点的数量(排除没有交点的情况)

  1 #include <iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stdlib.h>
  6 #include<vector>
  7 #include<cmath>
  8 #include<queue>
  9 #include<set>
 10 using namespace std;
 11 #define N 55
 12 #define LL long long
 13 #define INF 0xfffffff
 14 const double eps = 1e-10;
 15 const double pi = acos(-1.0);
 16 const double inf = ~0u>>2;
 17
 18 struct point
 19 {
 20     double x,y;
 21     point(double x=0,double y=0):x(x),y(y){}
 22 };
 23 vector<point>ed[N];
 24 vector<int>dd[N];
 25 vector<point>td[N];
 26 struct circle
 27 {
 28     point c;
 29     double r;
 30     point ppoint(double a)
 31     {
 32         return point(c.x+cos(a)*r,c.y+sin(a)*r);
 33     }
 34 };
 35 circle cp[N],cq[N];
 36 int fa[N];
 37 typedef point pointt;
 38 pointt operator -(point a,point b)
 39 {
 40     return point(a.x-b.x,a.y-b.y);
 41 }
 42
 43 int dcmp(double x)
 44 {
 45     if(fabs(x)<eps) return 0;
 46     return x<0?-1:1;
 47 }
 48
 49 bool operator == (const point &a,const point &b)
 50 {
 51     return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
 52 }
 53 double dis(point a)
 54 {
 55     return sqrt(a.x*a.x+a.y*a.y);
 56 }
 57 double angle(point a)//计算向量极角
 58 {
 59     return atan2(a.y,a.x);
 60 }
 61 double sqr(double x) {
 62
 63     return x * x;
 64
 65 }
 66
 67 bool intersection(const point& o1, double r1, const point& o2, double r2,int k,int kk)
 68 {
 69     double d = dis(o1- o2);
 70     if (d < fabs(r1 - r2) - eps || d > r1 + r2 + eps)
 71     {
 72         return false;
 73     }
 74     double cosa = (sqr(r1) + sqr(d) - sqr(r2)) / (2 * r1 * d);
 75     double sina = sqrt(max(0., 1. - sqr(cosa)));
 76     point p1 = o1,p2 = o1;
 77     p1.x += r1 / d * ((o2.x - o1.x) * cosa + (o2.y - o1.y) * -sina);
 78     p1.y += r1 / d * ((o2.x - o1.x) * sina + (o2.y - o1.y) * cosa);
 79     p2.x += r1 / d * ((o2.x - o1.x) * cosa + (o2.y - o1.y) * sina);
 80     p2.y += r1 / d * ((o2.x - o1.x) * -sina + (o2.y - o1.y) * cosa);
 81     //cout<<p1.x<<" --"<<p2.x<<" "<<o1.x<<" "<<o1.y<<" "<<o2.x<<" "<<o2.y<<endl;
 82     //printf("%.10f %.10f %.10f %.10f\n",p1.x,p1.y,p2.x,p2.y);
 83     ed[k].push_back(p1);
 84     ed[k].push_back(p2);
 85     ed[kk].push_back(p1);
 86     ed[kk].push_back(p2);
 87
 88     return true;
 89 }
 90 bool cmp(circle a, circle b)
 91 {
 92     if(dcmp(a.r-b.r)==0)
 93     {
 94         if(dcmp(a.c.x-b.c.x)==0)
 95         return a.c.y<b.c.y;
 96         return a.c.x<b.c.x;
 97     }
 98     return a.r<b.r;
 99 }
100 bool cmpp(point a,point b)
101 {
102     if(dcmp(a.x-b.x)==0)
103     return a.y<b.y;
104     return a.x<b.x;
105 }
106 int find(int x)
107 {
108     if(fa[x]!=x)
109     {
110         fa[x] = find(fa[x]);
111         return fa[x];
112     }
113     return x;
114 }
115 int main()
116 {
117     int t,i,j,n;
118     cin>>t;
119     while(t--)
120     {
121         scanf("%d",&n);
122         for(i = 1; i <= n ;i++)
123         {
124             ed[i].clear();fa[i] = i;
125             dd[i].clear();
126             td[i].clear();
127         }
128         for(i = 1; i <= n ;i++)
129         scanf("%lf%lf%lf",&cp[i].c.x,&cp[i].c.y,&cp[i].r);
130         sort(cp+1,cp+n+1,cmp);
131         int g = 1;
132         cq[g] = cp[g];
133         for(i = 2; i <= n; i++)
134         {
135             if(cp[i].c==cp[i-1].c&&dcmp(cp[i].r-cp[i-1].r)==0)
136             continue;
137             cq[++g] = cp[i];
138         }
139         for(i = 1; i <= g; i++)
140         {
141             for(j = i+1 ; j <= g; j++)
142             {
143                 int flag = intersection(cq[i].c,cq[i].r,cq[j].c,cq[j].r,i,j);
144                 if(flag == 0) continue;
145                 int tx = find(i),ty = find(j);
146                 fa[tx] = ty;
147             }
148         }
149         for(i = 1; i <= g;  i++)
150         {
151             int fx = find(i);
152             dd[fx].push_back(i);
153         }
154         int B=0,V=0;
155         int ans = 0;
156         int num = 0;
157         for(i = 1 ; i <= g; i++)
158         {
159             if(dd[i].size()==0) continue;
160             B = 0,V = 0;
161             for(j = 0 ;j < dd[i].size() ; j++)
162             {
163                 int u = dd[i][j];
164                 if(ed[u].size()==0)
165                 {
166                     B++;
167                     continue;
168                 }
169                 sort(ed[u].begin(),ed[u].end(),cmpp);
170                 td[i].push_back(ed[u][0]);
171                 int o = 1;
172                 for(int e = 1 ; e < ed[u].size() ; e++)
173                 {
174                     //printf("%.10f %.10f\n",ed[u][e].x,ed[u][e].y);
175                     td[i].push_back(ed[u][e]);
176                     if(ed[u][e]==ed[u][e-1]) continue;
177                     else o++;
178                 }
179                 B+=o;
180             }
181             sort(td[i].begin(),td[i].end(),cmpp);
182             V+=1;
183            // cout<<td[i].size()<<endl;
184             for(j = 1; j < td[i].size() ; j++)
185             {
186                 //printf("%.10f %.10f\n",td[i][j].x,td[i][j].y);
187                 if(td[i][j]==td[i][j-1]) continue;
188                 else V++;
189
190             }
191            // cout<<B+1-V<<" "<<B<<" "<<V<<endl;
192             ans+=B+1-V;
193         }
194         cout<<1+ans<<endl;
195     }
196     return 0;
197 }

zoj2589Circles(平面图的欧拉定理)

时间: 2024-08-25 07:27:04

zoj2589Circles(平面图的欧拉定理)的相关文章

LA 3263 (平面图的欧拉定理) That Nice Euler Circuit

题意: 平面上有n个端点的一笔画,最后一个端点与第一个端点重合,即所给图案是闭合曲线.求这些线段将平面分成多少部分. 分析: 平面图中欧拉定理:设平面的顶点数.边数和面数分别为V.E和F.则 V+F-E=2 所求结果不容易直接求出,因此我们可以转换成 F=E-V+2 枚举两条边,如果有交点则顶点数+1,并将交点记录下来 所有交点去重(去重前记得排序),如果某个交点在线段上,则边数+1 1 //#define LOCAL 2 #include <cstdio> 3 #include <cs

poj2284 That Nice Euler Circuit(欧拉公式)

题目链接:poj2284 That Nice Euler Circuit 欧拉公式:如果G是一个阶为n,边数为m且含有r个区域的连通平面图,则有恒等式:n-m+r=2. 欧拉公式的推广: 对于具有k(k≥2)个连通分支的平面图G,有:n-m+r=k+1. 题意:给出连通平面图的各顶点,求这个欧拉回路将平面分成多少区域. 题解:根据平面图的欧拉定理“n-m+r=2”来求解区域数r. 顶点个数n:两两线段求交点,每个交点都是图中的顶点. 边数m:在求交点时判断每个交点落在第几条边上,如果一个交点落在

计算几何题目分类

转载 一.基础题目 1.1 有固定算法的题目 A, 最近点对问题最近点对问题的算法基于扫描线算法.ZOJ 2107    Quoit Design    典型最近点对问题POJ    3714    Raid    变种最近点对问题 B,最小包围圆最小包围圆的算法是一种增量算法,期望是O(n).ZOJ    1450    Minimal Circle  HDU    3007    Buried memory C,旋转卡壳POJ 3608    Bridge Across Islands   

LA 3236 That Nice Euler Circuit(欧拉定理)

That Nice Euler Circuit Timelimit:3.000 seconds Little Joey invented a scrabble machine that he called Euler, after the great mathematician. In his primary school Joey heard about the nice story of how Euler started the study about graphs. The proble

LA_3263_That_Nice_Euler_Circuits_(欧拉定理+计算几何)

描述 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=15&page=show_problem&problem=1264 给出一个一笔画的所有折点,求这个一笔画共把平面分成了几个区域(包括优先区域与无限区域). 3263 - That Nice Euler Circuit 3263That Nice Euler CircuitLittle Joey i

HDU 1665 - Different Digits(几何 + 欧拉定理)

题意:在一个平面上,给定一个由 n 个点(4 <= n <= 300)组成的一封闭笔画图形(第一个端点与第 n 个端点重合),求这个图形将平面分成几个部分. 需要用到欧拉定理: 欧拉定理:设图的顶点数为 v ,边数(三维中为棱的个数)为 e ,面数为 f ,则v + f - e = 2. 则若求面数,只要求出顶点数 v 和边数 e,即能得出答案 f = e + 2 - v. (注意:这里的边数 e,是指的单独一条线段,若中间被点分隔开,则算作多条线段而非一条) 具体处理如下: 1.先枚举任意两

平面上欧拉定理:poj 2284( LA 3263 ) That Nice Euler Circuit

3263 - That Nice Euler Circuit Time limit: 3.000 seconds Description Little Joey invented a scrabble machine that he called Euler, after the great mathematician. In his primary school Joey heard about the nice story of how Euler started the study abo

BZOJ 4541: [Hnoi2016]矿区 平面图转对偶图+DFS树

4541: [Hnoi2016]矿区 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 433  Solved: 182[Submit][Status][Discuss] Description 平面上的矿区划分成了若干个开发区域.简单地说,你可以将矿区看成一张连通的平面图,平面图划分为了若 干平面块,每个平面块即为一个开发区域,平面块之间的边界必定由若干整点(坐标值为整数的点)和连接这些整点 的线段组成.每个开发区域的矿量与该开发区域的面积有关:具

bzoj3051: [wc2013]平面图

Description Input Output 扫描线求出平面图的对偶图然后求最小生成树,用并查集按秩合并,以便查询两点间路径最大权 #include<stdio.h> #include<algorithm> #include<vector> #include<set> #include<cmath> int f[200007],f2[200007],h2[200007]; int get(int*f,int x){ int a=x,c; wh