【模板】【两圆相交】【平面欧拉定理】zoj2589

题目链接:https://zoj.pintia.cn/problem-sets/91827364500/problems/91827366088

欧拉定理 V - E + R = 2 (V:顶点 E:边 R:面)

两圆相交模板:

 1 // p1,p2是交点
 2 inline bool operator<(const Point& lhs, const Point& rhs) {
 3     if (fabs(lhs.x - rhs.x) > 1e-8) {
 4         return lhs.x < rhs.x;
 5     } else if (fabs(lhs.y - rhs.y) > 1e-8) {
 6         return lhs.y < rhs.y;
 7     } else {
 8         return false;
 9     }
10 }
11 double dis(Point a,Point b){
12     return sqrt( (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
13 }
14 double sqr(double x){return x*x;}
15 bool intersection(Point o1, double r1,  Point o2, double r2, Point& p1, Point& p2) {
16     double d = dis(o1, o2);
17     if (d < fabs(r1 - r2) - eps || d > r1 + r2 + eps) {
18         return false;
19     }
20     double cosa = (sqr(r1) + sqr(d) - sqr(r2)) / (2 * r1 * d);
21     double sina = sqrt(max(0.0, 1.0 - sqr(cosa)));
22     p1 = p2 = o1;
23     p1.x += r1 / d * ((o2.x - o1.x) * cosa + (o2.y - o1.y) * -sina);
24     p1.y += r1 / d * ((o2.x - o1.x) * sina + (o2.y - o1.y) * cosa);
25     p2.x += r1 / d * ((o2.x - o1.x) * cosa + (o2.y - o1.y) * sina);
26     p2.y += r1 / d * ((o2.x - o1.x) * -sina + (o2.y - o1.y) * cosa);
27     return true;
28 }
View Code

 

代码:

 1 //欧拉定理 V - E + R = 2 (V:顶点 E:边 R:面)
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 #define eps 1e-6
 5 const int N = 60;
 6 typedef long long ll;
 7 struct Point{
 8     double x,y;
 9 };
10 struct Circle{
11     Point o;
12     double r;
13 }c[N];
14 set<Point> st1[N],st2[N];
15 int fa[N],E[N];
16 // p1,p2是交点
17 inline bool operator<(const Point& lhs, const Point& rhs) {
18     if (fabs(lhs.x - rhs.x) > 1e-8) {
19         return lhs.x < rhs.x;
20     } else if (fabs(lhs.y - rhs.y) > 1e-8) {
21         return lhs.y < rhs.y;
22     } else {
23         return false;
24     }
25 }
26 double dis(Point a,Point b){
27     return sqrt( (a.x - b.x)*(a.x - b.x) + (a.y - b.y)*(a.y - b.y));
28 }
29 double sqr(double x){return x*x;}
30 bool intersection(Point o1, double r1,  Point o2, double r2, Point& p1, Point& p2) {
31     double d = dis(o1, o2);
32     if (d < fabs(r1 - r2) - eps || d > r1 + r2 + eps) {
33         return false;
34     }
35     double cosa = (sqr(r1) + sqr(d) - sqr(r2)) / (2 * r1 * d);
36     double sina = sqrt(max(0.0, 1.0 - sqr(cosa)));
37     p1 = p2 = o1;
38     p1.x += r1 / d * ((o2.x - o1.x) * cosa + (o2.y - o1.y) * -sina);
39     p1.y += r1 / d * ((o2.x - o1.x) * sina + (o2.y - o1.y) * cosa);
40     p2.x += r1 / d * ((o2.x - o1.x) * cosa + (o2.y - o1.y) * sina);
41     p2.y += r1 / d * ((o2.x - o1.x) * -sina + (o2.y - o1.y) * cosa);
42     return true;
43 }
44 
45 int find(int x){
46     if(fa[x] == x) return x;
47     return fa[x] = find(fa[x]); 
48 }
49 
50 int main(){
51     int T; scanf("%d",&T);
52     while(T--){
53         int n; scanf("%d",&n);
54         for(int i = 1;i<=n;++i) scanf("%lf %lf %lf",&c[i].o.x,&c[i].o.y,&c[i].r);
55         for(int i = 1;i<=n;++i) fa[i] = i,st1[i].clear(),st2[i].clear(),E[i]=0;
56         Point p1,p2;
57         for(int i = 2;i<=n;++i){
58             for(int j = i-1;j>=1;--j){
59                 if(intersection(c[i].o,c[i].r,c[j].o,c[j].r,p1,p2)){
60                     int f = find(j);
61                     fa[f] = i;
62                 }
63             }
64         }
65         for(int i = 2;i<=n;++i){
66             for(int j = i-1;j>=1;--j){
67                 if(!intersection(c[i].o,c[i].r,c[j].o,c[j].r,p1,p2)) continue;
68                 int f = find(i);
69                 st2[f].insert(p1); st2[f].insert(p2);
70                 st1[i].insert(p1); st1[i].insert(p2);
71                 st1[j].insert(p1); st1[j].insert(p2);
72             }
73         }
74         for(int i = 1;i<=n;++i){
75             int f = find(i);
76             E[f] += st1[i].size();
77         }
78         ll ans = 1;
79         for(int i = 1;i<=n;++i){
80             int f = find(i);
81             if(f != i) continue;
82             ans += (ll)1 - (int)st2[i].size() + E[i];
83         }
84         printf("%lld\n",ans);
85     }
86     return 0;
87 }
View Code

 

posted @ 2019-10-15 20:51  小布鞋  阅读(423)  评论(0编辑  收藏  举报