Gym - 100625G Getting Through 计算几何+并查集

来源:互联网 发布:千万不要相信网络拍卖 编辑:程序博客网 时间:2024/05/20 06:24
http://codeforces.com/gym/100625/attachments/download/3213/2013-benelux-algorithm-programming-contest-bapc-13-en.pdf

题意:平面内给你一个y轴为左边界,宽度为w的长条形区域,区域内n个半径为r的圆,问你最大能够通过这个区域的圆的半径是多少。

思路:这题和POJ 3798差不是很多,感觉像是简化版。之前鲍佳提到过那个题,谈到过并查集,不过我没写过。知道并查集这题就很好想了,在圆与圆,圆与左右边界之间都连一条边,边长就是他们的距离。那么答案就是这些边中的一条了。现在将边排好序,从小到大加到并查集里面,每加一次find一下左边界和右边界是不是连到一起了,如果连起来了,那这条边就是答案,直接输出。最后还没连起来的话,就无解了。

  1 #pragma comment(linker, "/STACK:1000000000")  2 #include <iostream>  3 #include <cstdio>  4 #include <fstream>  5 #include <algorithm>  6 #include <cmath>  7 #include <deque>  8 #include <vector>  9 #include <queue> 10 #include <string> 11 #include <cstring> 12 #include <map> 13 #include <stack> 14 #include <set> 15 #define LL long long 16 #define MAXN 1005 17 #define INF 0x3f3f3f3f 18 #define eps 1e-8 19 using namespace std; 20 struct Circle 21 { 22     int x, y, r; 23 }; 24 struct Node 25 { 26     int from, to; 27     double dis; 28     Node(int from, int to, double dis):from(from), to(to), dis(dis){}; 29 }; 30 Circle a[MAXN]; 31 vector<Node> p; 32 int father[MAXN]; 33 double GetDis(int u, int v) 34 { 35     double x = abs(a[u].x - a[v].x); 36     double y = abs(a[u].y - a[v].y); 37     double r = a[u].r + a[v].r; 38     return sqrt(x * x + y * y) - r; 39 } 40 int find(int x) 41 { 42     if(x == father[x]) return x; 43     father[x] = find(father[x]); 44     return father[x]; 45 } 46 bool compare(Node a, Node b) 47 { 48     return a.dis < b.dis; 49 } 50 int main() 51 { 52 #ifndef ONLINE_JUDGE 53     freopen("in.txt", "r", stdin); 54     //freopen("out.txt", "w", stdout); 55 #endif // OPEN_FILE 56     int T; 57     scanf("%d", &T); 58     while(T--){ 59         int w; 60         scanf("%d", &w); 61         int n; 62         scanf("%d", &n); 63         if(n == 0){ 64             double ans = w; 65             ans /= 2; 66             printf("%.7lf\n", ans); 67             continue; 68         } 69         for(int i = 1; i <= n; i++){ 70             scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].r); 71         } 72         for(int i = 0; i <= n + 1; i++){ 73             father[i] = i; 74         } 75         p.clear(); 76         for(int i = 1; i <= n; i++){ 77             for(int j = i + 1; j <= n; j++){ 78                 p.push_back(Node(i, j, GetDis(i, j))); 79             } 80         } 81         for(int i = 1; i <= n; i++){ 82             p.push_back(Node(i, 0, a[i].x - a[i].r)); 83             p.push_back(Node(i, n + 1, w - a[i].x - a[i].r)); 84         } 85         n++; 86         sort(p.begin(), p.end(), compare); 87         int m = p.size(); 88         double ans = 0; 89         bool flag = false; 90         for(int i = 0; i < p.size(); i++){ 91             int x = find(p[i].from); 92             int y = find(p[i].to); 93             if(x == y) continue; 94             father[x] = y; 95             x = find(0); 96             y = find(n); 97             if(x == y && p[i].dis > 0){ 98                 ans = p[i].dis; 99                 flag = true;100                 break;101             }102         }103         if(flag){104             printf("%.7lf\n", ans / 2);105         }106         else{107             printf("0\n");108         }109     }110 }

 

0 0
原创粉丝点击