UVA10301 Rings and Glue【并查集】

Little John is in big trouble. Playing with his different-sized (and colored!) rings and glue seemed
such a good idea. However, the rings now lay on the floor, glued together with some-thing that will
definitely not come off with water. Surprisingly enough, it seems like no rings are actually glued to the
floor, only to other rings. How about that!
You must help Little John to pick the rings off the floor before his mom comes home from work.
Since the glue is dry by now, it seems like an easy enough task. This is not the case. Little John is
an irrational kid of numbers, and so he has decided to pick up the largest component (most rings) of
glued-together rings first. It is the number of rings in this largest component you are asked to find.
Two rings are glued together if and only if they overlap at some point but no rings will ever overlap
in only a single point. All rings are of the doughnut kind (with a hole in them). They can however,
according to Little John, be considered “infinitely thin”.
Input
Input consists of a number (> 0) of problems. Each problem starts with the number of rings, n, where
0 ≤ n < 100. After that, n rows follow, each containing a ring’s physical attributes. That is, 3 floating
point numbers, with an arbitrary number of spaces between them, describing the x coordinate and y
coordinate for its center and its radius. All floating point numbers fit into the standard floating point
type of your favorite programming language (e.g., float for C/C++). Input ends with a single row
with the integer ‘-1’.
Output
Output consists of as many grammatically correct answers as there were problems, each answer, on a
separate line, being ‘The largest component contains X ring(s).’ where X is the number of rings
in the largest component.
Sample Input
4
0.0 0.0 1.0
-1.5 -1.5 0.5
1.5 1.5 0.5
-2.0 2.0 3.5
3
3.0 2.0 2.0
0.0 -0.5 1.0
0.0 0.0 2.0
5
-2.0 0.0 1.0
1.0 -1.0 1.0
0.0 1.0 0.5
2.0 0.0 1.0
-1.0 1.0 1.0
-1
Sample Output
The largest component contains 4 rings.
The largest component contains 2 rings.
The largest component contains 3 rings.

问题链接UVA10301 Rings and Glue
问题简述:(略)
问题分析
    N个粘有胶水的圆圈掉到地下,给定这些圆圈的圆心坐标和半径,问有粘在一起的最多的圆圈有几个。
    用并查集,并且枚举任意两个圆圈判定一下是否粘在一起。需要注意的是,有可能出现圆圈半径大小不同,一个套在另外一个之内而没有粘在一起的情况。还要考虑N=0的情况。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* UVA10301 Rings and Glue */

#include <bits/stdc++.h>

using namespace std;

const double EPS = 1e-6;

const int N = 100;
int f[N], sum[N];

void UFInit(int n)
{
    for(int i = 0; i < n; i++)
        f[i] = i, sum[i] = 1;
}

int Find(int a) {
    return a == f[a] ? a : f[a] = Find(f[a]);
}

void Union(int a, int b)
{
    int x = Find(a);
    int y = Find(b);
    if (x != y) {
        f[x] = y;
        sum[y] += sum[x];
        sum[a] = sum[b] = sum[x] = sum[y];
    }
}

struct Circle {
    double x, y, r;
} c[N];

double dist(Circle& a, Circle& b)
{
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

int main()
{
    int n;
    while(~scanf("%d", &n) && n >= 0) {
        UFInit(n);

        for(int i = 0; i < n; i++)
            scanf("%lf%lf%lf", &c[i].x, &c[i].y, &c[i].r);

        for(int i = 0; i < n; i++)
            for(int j = i + 1; j < n; j++)
                if( dist(c[i], c[j]) - (c[i].r + c[j].r) < EPS && fabs(c[i].r - c[j].r) - dist(c[i], c[j]) < EPS)
                    Union(i, j);

        int maxcnt = 0;
        for(int i = 0; i < n; i++)
            maxcnt = max(maxcnt, sum[i]);

        if(maxcnt > 1 || maxcnt == 0)
            printf("The largest component contains %d rings.\n", maxcnt);
        else
            printf("The largest component contains 1 ring.\n");
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/tigerisland45/article/details/89822345