POJ 2236 Wireless Network

来源:互联网 发布:中华田园犬 知乎 编辑:程序博客网 时间:2024/06/04 18:53

并查集

题意

若两台修好的计算机之间的距离小于等于d时可以直接通信;
若两个计算机A、B和中间计算机C满足(A和C的距离,B和C的距离小于等于d),则A和B可以通信
O i 表示将i号计算机修好; S i j 问i和j是否能通信

题解

使用并查集。

“O i”: i没有所属集合时(par[i] == i)会将i加入和它相连且已维修节点的所属集合,后续会继续合并i所属集合 和 i相连集合

“S i j” :查看i和j是否属于一个集合

代码

#include <iostream>#include <queue>#include <vector>#include <algorithm>#include <cmath>#include <cstring>using namespace std;const int MAXN = 10010;int N,d;struct Point{    int x;    int y;    int par;};Point comp[MAXN];bool repair[MAXN];int find_root(int x){    int r = x;    while(comp[r].par != r)        r = comp[r].par;    int i = x;    while(i != r) // compress the path    {        int t = comp[i].par;        comp[i].par = r;        i = t;    }    return r;}void join(int node){    repair[node] = true;    for(int i = 1; i <= N; i++)    {        if(i != node && repair[i])        {            double dis = pow(comp[i].x - comp[node].x, 2) + pow(comp[i].y - comp[node].y, 2) ;            if(dis <= d * d)            {                int root1 = find_root(i);                int root2 = find_root(node);                if(root1 != root2)                {                    comp[root2].par = root1;                }            }        }    }}int main(){    cin >> N >> d;    for(int i = 1; i <= N; i++)    {        cin >> comp[i].x >> comp[i].y;        comp[i].par = i;    }    memset(repair, false, sizeof(repair));    char temp[MAXN];    while(cin >> temp)    {        switch(temp[0])        {            case 'O':                int opr;                cin >> opr;                join(opr);                break;            case 'S':                int x,y;                cin >> x >> y;                if(find_root(x) == find_root(y))                {                    cout << "SUCCESS" <<endl;                }                else                    cout << "FAIL" <<endl;                break;        }    }    return 0;}
0 0
原创粉丝点击