POJ 2236 Wireless Network(并查集)

预处理一下每个点的相邻点,直接并查集。(不要吐槽为什么在做水题,我只是来测试一下算法效率的...

路径压缩加了按秩合并的优化效果不明显(24ms,不稳定),大概是路径压缩的上界很松吧。

#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<algorithm>
#include<cmath>
//#include<bits/stdc++.h>
using namespace std;

#define PB push_back
const int maxn = 1e3+2;
double x[maxn], y[maxn];
bool vis[maxn];
vector<int> nei[maxn];
inline double squ(double a){ return a*a; }
inline double dist(int i,int j){ return sqrt(squ(x[i]-x[j])+squ(y[i]-y[j])); }
const int eps = 1e-9;
int pa[maxn], hei[maxn];
int fdst(int x){ return x==pa[x]?x:pa[x]=fdst(pa[x]); }
inline void mrge(int a,int b)
{
    int s1 = fdst(a), s2 = fdst(b);
    if(s1 != s2){
        if(hei[s1] < hei[s2]) pa[s1] = s2;
        else {
            pa[s2] = s1;
            if(hei[s1] == hei[s2]) hei[s1]++;
        }
    }
}

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    int N, d; scanf("%d%d",&N,&d);
    for(int i = 1; i <= N; i++){
        scanf("%lf%lf",x+i,y+i);
        pa[i] = i;
    }
    for(int i = 1; i <= N; i++){
        for(int j = 1; j < i; j++){
            if(dist(i,j)<= d){
                nei[i].PB(j);
                nei[j].PB(i);
            }
        }
    }
    char op[2];
    int p,q;
    while(~scanf("%s",op)){
        scanf("%d",&p);
        if(*op=='O'){
            if(vis[p]) continue;
            vis[p] = true;
            for(int i = 0; i < (int)nei[p].size(); i++){
                if(vis[nei[p][i]])
                    mrge(p,nei[p][i]);
            }
        }else {
            scanf("%d",&q);
            puts(fdst(p) == fdst(q)?"SUCCESS":"FAIL");
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/jerryRey/p/4889452.html