您的位置:首页 > 其它

[POJ 2236]Wireless Network[并查集]

2015-08-28 20:23 393 查看
题目链接:[POJ 2236]Wireless Network[并查集]

题意分析:

电脑网络全部被破坏了,如今能做的是两个操作:一、修复某个电脑;二、查询两个电脑间能否交流。两台电脑能交流的情况是:两台都被修复了,并且两台相距小于d米或者两台之间能借由其它电脑相互联系

解题思路:

当某台电脑被修复时,遍历所有它能连接到的结点,如果所连接结点是被修复的,就将它归入到同一集合。这样每次查询的时候就是O(1)的查询了。

个人感受:

脑子没转过来,想到查询的时候是dfs。。。。。简直了。。。。嘛,还是染色的时候更新比较合理XD

具体代码如下:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;

const int INF = 0x7f7f7f7f;
const int MAXN = 1e3 + 111;

int p[MAXN];
bool repair[MAXN];
double x[MAXN], y[MAXN];
vector<int> G[MAXN]; //记录可达点

double getDis(int a, int b)
{
    double dx = x[a] - x[b], dy = y[a] - y[b];
    return sqrt(dx*dx + dy*dy);
}

int find(int x)
{
    return p[x] == x? x : p[x] = find(p[x]);
}

void unite(int a, int b)
{
    a = find(a), b = find(b);
    p[a] = b;
}

int main()
{
    int n, a, b;
    double d;
    scanf("%d%lf", &n, &d);
    for (int i = 1; i <= n; ++i)
    {
        p[i] = i;
        scanf("%lf%lf", &x[i], &y[i]);
    }
    for (int i = 1; i <= n; ++i)
        for (int j = i + 1; j <= n; ++j)
        {
            if (getDis(i, j) <= d)
            {
                G[i].push_back(j);
                G[j].push_back(i);
            }
        }
    char op[2];
    while (~scanf("%s", op))
    {
        if (op[0] == 'O')
        {
            scanf("%d", &a);
            repair[a] = 1;
            for (int i = 0; i < G[a].size(); ++i) //合并更新点周围被更新的点
            {
                int v = G[a][i];
                if (repair[v]) unite(a, v);
            }
        }
        else
        {
            scanf("%d%d", &a, &b);
            if (find(a) == find(b)) printf("SUCCESS\n");
            else printf("FAIL\n");
        }
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: