POJ 2236 Wireless Network(并查集)

来源:互联网 发布:淘宝电子书商城 编辑:程序博客网 时间:2024/05/16 05:43


http://poj.org/problem?id=2236


题意:给出一些电脑,它们目前都是损坏的状态,然后会依次修其中的一些,如果两台电脑都被修好了,并且它们之间的距离小于等于d,那么这两台电脑是可以沟通的。如果AB可以沟通,BC可以沟通,那么AC也是可以沟通的。现在查询两台电脑的时候,问它们是不是可以沟通的。


刚开始的时候,每一台电脑都是一个集合。每一个集合之内的电脑都可以互相沟通,不同集合内的电脑目前不可以沟通。某一台电脑A刚被修好的时候,要把其他已经维修好的电脑都枚举一遍,如果B距离符合要求,那么就说明这两台电脑之间可以沟通,那么A和B所在的集合中所有的电脑都可以沟通,A所在的集合和B所在的集合可以合并。处理好了以后,那么当前状态下,还是满足每一个集合内的电脑都可以互相沟通,不同集合内的电脑目前不可以沟通(比如两个不同集合中有CD,A在修好之前两者不能沟通,现在想要沟通一定也只能靠A作为桥梁,A连上C所在集合中任何一台电脑并且连上D所在集合中的任何一台电脑就可以,但是刚才A已经和每一台电脑都试过了,如果可以连上一定是会合并集合的,不会出现现在不同集合的情况。有点类似归纳法,到最后一步,还是满足的。


不要忘了初始化。

#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#include<queue>#include<vector>#include<string>#define MAXN 1005using namespace std;int n, d, p, q, m;char s[20];int Par[MAXN], Rank[MAXN], re[MAXN], X[MAXN], Y[MAXN];bool OK(int u, int v){    if ((X[u] - X[v]) * (X[u] - X[v]) + (Y[u] - Y[v]) * (Y[u] - Y[v]) <= d * d) return true;    else return false;}void init(int n){    for (int i = 0; i < n; i++)    {        Par[i] = i;        Rank[i] = 0;    }}int Find(int x){    if (Par[x] == x)    {        return x;    }    else    {        return Par[x] = Find(Par[x]); //路径压缩    }}void unite(int x, int y){    x = Find(x);    y = Find(y);    if (x == y) return;    if (Rank[x] < Rank[y])    {        Par[x] = y;    }    else    {        Par[y] = x;        if (Rank[x] == Rank[y]) Rank[x]++;    }}bool same(int x, int y){    return Find(x) == Find(y);}int main(){    scanf("%d%d", &n, &d);    for (int i = 0; i < n; i++) scanf("%d%d", &X[i], &Y[i]);    memset(re, 0, sizeof(re));    init(n);    while (~scanf("%s", s))    {        if (s[0] == 'O')        {            scanf("%d", &m);            m--;            for (int i = 0; i < n; i++)                if (OK(m, i) && re[i] == 1 && m != i)            {                unite(m, i);            }            re[m] = 1;        }        if (s[0] == 'S')        {            scanf("%d%d", &p, &q);            p--;            q--;            if (same(p, q)) printf("SUCCESS\n");            else printf("FAIL\n");        }    }    return 0;}

0 0
原创粉丝点击