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

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 }

 

posted on 2015-08-10 15:29  张济  阅读(331)  评论(0编辑  收藏  举报

导航