基础并查集01(poj2236)

来源:互联网 发布:中国 程序员 总数 2017 编辑:程序博客网 时间:2024/05/14 16:14

并查集,又一个acm的重点,对于分群具有特别好的效果


A.Wireless Network


思路:这一题的关键就是读题,确实题意有点晦涩,需要研究一番。

乍一看题目有点像最短路问题,仔细研究发现,给定了坐标,给定了最长距离并且传输过程可以由中间点中转,那么这一题就相当于将距离小于给定长度的点分于一个集体,内部相互可达,于是,并查集的思路瞬间开朗。


#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>using namespace std;const int maxn = 1010;int x[maxn],y[maxn];int pre[maxn];bool repair[maxn];bool getdis(int a,int b,int d){    int dis = (x[a] - x[b])*(x[a] - x[b]) + (y[a] - y[b])*(y[a] - y[b]);    if(d>=dis)    {        return true;    }    else    {        return false;    }}int finds(int x){ //寻找    int r = x;    while(pre[r]!=r){        r = pre[r];    }    int i=x ,j;    while(pre[i]!=r){ //路径压缩        j = pre[i];        pre[i] = r;        i = j;    }    return r;}void join(int x,int y){ //将两个集合合并    int fx = finds(x);    int fy = finds(y);    if(fx > fy){int temp = fx;fx = fy;fy = temp;}    if(fx!=fy){        pre[fy] = fx;    }}vector <int> re;int main(){    int n,d;    scanf("%d%d",&n,&d);    d = d * d;    re.clear();    for(int i=1;i<=n;i++)    {        pre[i] = i;        scanf("%d%d",&x[i],&y[i]);        repair[i]=false;    }    char temp[5];    while(scanf("%s",temp)!=EOF)    {        if(strcmp(temp,"O")==0)        {            int computer;            scanf("%d",&computer);            vector <int> :: iterator it = re.begin();            for(;it!=re.end();it++)            {                if(getdis(computer,(*it),d))                {                    join(computer,(*it));                }            }            re.push_back(computer);            repair[computer] = true;        }        else        {            int p,q;            scanf("%d%d",&p,&q);            if(repair[p]&&repair[q]&&finds(p)==finds(q))            {                printf("SUCCESS\n");            }            else            {                printf("FAIL\n");            }        }    }    return 0;}


1 0
原创粉丝点击