4266. 无线网络
4266
考点:合并和查询
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1010;
int n, m, d;
int x[N], y[N];
int p[N];
bool g[N][N], st[N];//g是判断距离,st是判断开没开机
int find(int x) // 并查集
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
bool check(int a,int b)
{
int dx = abs(x[a] - x[b]);
int dy = abs(y[a] - y[b]);
if (dx * dx + dy * dy <= d * d) return true;
return false;
}
int main()
{
cin>>n>>d;
for(int i=1;i<=n;i++)
cin>>x[i]>>y[i];
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ )
if (check(i, j))
g[i][j] = true;
for(int i=0;i<=n;i++)p[i]=i;
char op;
int a, b;
while (cin >> op)
{
if (op == 'O') // 最多开机 n 次,时间复杂度 O(n * n + m)
{
scanf("%d", &a);
for (int i = 1; i <= n; i ++ )
if (st[i] && g[i][a])//st[i]==true,说明开机了
{
int fa = find(a), fb = find(i);//合并
p[fa] = fb;
}
st[a] = true;
}
else
{
scanf("%d%d", &a, &b);
int fa = find(a);
int fb = find(b);
if (fa == fb) cout << "SUCCESS" << endl;//查询
else cout << "FAIL" << endl;
}
}
return 0;
}
4267. 可疑人员
4267
考点:合并
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=3e5+10;
int a[N],p[N];
int n,m,k;
int sizee[N];
int find(int x) // 并查集
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(0);
while(cin>>n>>m,n||m)
{
for(int i=0;i<n;i++)
p[i]=i,sizee[i]=1;
for(int i=1;i<=m;i++)//合并
{
int k;
cin>>k;
if(k==0)continue;
int x,y;
cin>>x;//把每个社团的第一个人读进来
for(int j=2;j<=k;j++)
{
cin>>y;
int px=find(x),py=find(y);
if(px!=py)
{
sizee[py] += sizee[px];
p[px]=py;
}
}
}
int res=0;
cout<<sizee[find(0)]<<endl;
}
return 0;
}
//维护每个集合中的元素个数