无线网络(预处理+并查集)
Posted MangataTS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了无线网络(预处理+并查集)相关的知识,希望对你有一定的参考价值。
题目链接
https://www.acwing.com/problem/content/4269/
思路
因为n的范围为1k,那么我们可以提前将每一个点在d范围内的所有点存储起来,这个也就是一条还不清楚能否连接的边,我们再用一个 v i s [ i ] vis[i] vis[i]记录一下当前第i台电脑是否开机。关于这些电脑之间的关系我们可以通过并查集维护在同一个集合中的电脑,我们现在有两种操作:
- 'O’操作:将p电脑开机
- 'S’操作:查询p和q是否在一个集合中
那么前面提到了我们通过并查集维护这个数据关系,对于第一种操作,我们就将p电脑周围所有的开机的电脑合并(merge操作)并将当前的电脑标记为开机,对于第二种操作我们直接查询p电脑和q电脑是否是同一个集合中即可
代码
#include<bits/stdc++.h>
using namespace std;
//----------------自定义部分----------------
#define ll long long
#define mod 1000000007
#define endl "\\n"
#define PII pair<int,int>
#define INF 0x3f3f3f3f
int dx[4] = -1, 0, 1, 0, dy[4] = 0, 1, 0, -1;
ll ksm(ll a,ll b)
ll ans = 1;
for(;b;b>>=1LL)
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
return ans;
ll lowbit(ll x)return -x & x;
const int N = 1e3+10;
//----------------自定义部分----------------
ll t,n,d,m,fa[N];
struct Point
ll x,y;
;
vector<Point> V;
vector<int> E[N];
bool vis[N];
ll find(ll x)
ll t = x;
while(t != fa[t]) t = fa[t];
while(x != fa[x])
ll temp = fa[x];
fa[x] = t;
x = temp;
return x;
bool is_in(Point a,Point b)
ll x = (a.x - b.x),y = (a.y - b.y);
ll len = x * x + y * y;
return len <= d * d;
void init()
ll x,y;
V.clear();
V.push_back(0,0);
for(int i = 1;i <= n; ++i)
vis[i] = false;
fa[i] = i;
cin>>x>>y;
V.push_back(x,y);
E[i].clear();
for(int i = 1;i <= n; ++i)
for(int j = 1;j <= n; ++j)
if(i == j) continue;
if(is_in(V[i],V[j]))
E[i].push_back(j);
void slove()
init();
char op;
while(cin>>op)
ll u,v,k;
if(op == 'O')
cin>>u;
k = find(u);
for(int i = 0,l = E[u].size();i < l; ++i)
if(!vis[E[u][i]]) continue;
v = find(E[u][i]);
if(k != v) fa[v] = k;
vis[u] = true;
else
cin>>u>>v;
u = find(u),v = find(v);
if(u == v)
cout<<"SUCCESS"<<endl;
else
cout<<"FAIL"<<endl;
int main()
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
while(cin>>n>>d)
slove();
return 0;
以上是关于无线网络(预处理+并查集)的主要内容,如果未能解决你的问题,请参考以下文章